1 /* Array translation routines
2 Copyright (C) 2002-2013 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
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
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
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/>. */
22 /* trans-array.c-- Various array related code, including scalarization,
23 allocation, initialization and other support routines. */
25 /* How the scalarizer works.
26 In gfortran, array expressions use the same core routines as scalar
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.
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.
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.
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.
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
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.
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.
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.
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.
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. */
80 #include "coretypes.h"
82 #include "gimple.h" /* For create_tmp_var_name. */
83 #include "diagnostic-core.h" /* For internal_error/fatal_error. */
86 #include "constructor.h"
88 #include "trans-stmt.h"
89 #include "trans-types.h"
90 #include "trans-array.h"
91 #include "trans-const.h"
92 #include "dependency.h"
94 static bool gfc_get_array_constructor_size (mpz_t
*, gfc_constructor_base
);
96 /* The contents of this structure aren't actually used, just the address. */
97 static gfc_ss gfc_ss_terminator_var
;
98 gfc_ss
* const gfc_ss_terminator
= &gfc_ss_terminator_var
;
102 gfc_array_dataptr_type (tree desc
)
104 return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc
)));
108 /* Build expressions to access the members of an array descriptor.
109 It's surprisingly easy to mess up here, so never access
110 an array descriptor by "brute force", always use these
111 functions. This also avoids problems if we change the format
112 of an array descriptor.
114 To understand these magic numbers, look at the comments
115 before gfc_build_array_type() in trans-types.c.
117 The code within these defines should be the only code which knows the format
118 of an array descriptor.
120 Any code just needing to read obtain the bounds of an array should use
121 gfc_conv_array_* rather than the following functions as these will return
122 know constant values, and work with arrays which do not have descriptors.
124 Don't forget to #undef these! */
127 #define OFFSET_FIELD 1
128 #define DTYPE_FIELD 2
129 #define DIMENSION_FIELD 3
130 #define CAF_TOKEN_FIELD 4
132 #define STRIDE_SUBFIELD 0
133 #define LBOUND_SUBFIELD 1
134 #define UBOUND_SUBFIELD 2
136 /* This provides READ-ONLY access to the data field. The field itself
137 doesn't have the proper type. */
140 gfc_conv_descriptor_data_get (tree desc
)
144 type
= TREE_TYPE (desc
);
145 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
147 field
= TYPE_FIELDS (type
);
148 gcc_assert (DATA_FIELD
== 0);
150 t
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
), desc
,
152 t
= fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type
), t
);
157 /* This provides WRITE access to the data field.
159 TUPLES_P is true if we are generating tuples.
161 This function gets called through the following macros:
162 gfc_conv_descriptor_data_set
163 gfc_conv_descriptor_data_set. */
166 gfc_conv_descriptor_data_set (stmtblock_t
*block
, tree desc
, tree value
)
170 type
= TREE_TYPE (desc
);
171 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
173 field
= TYPE_FIELDS (type
);
174 gcc_assert (DATA_FIELD
== 0);
176 t
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
), desc
,
178 gfc_add_modify (block
, t
, fold_convert (TREE_TYPE (field
), value
));
182 /* This provides address access to the data field. This should only be
183 used by array allocation, passing this on to the runtime. */
186 gfc_conv_descriptor_data_addr (tree desc
)
190 type
= TREE_TYPE (desc
);
191 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
193 field
= TYPE_FIELDS (type
);
194 gcc_assert (DATA_FIELD
== 0);
196 t
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
), desc
,
198 return gfc_build_addr_expr (NULL_TREE
, t
);
202 gfc_conv_descriptor_offset (tree desc
)
207 type
= TREE_TYPE (desc
);
208 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
210 field
= gfc_advance_chain (TYPE_FIELDS (type
), OFFSET_FIELD
);
211 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
213 return fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
214 desc
, field
, NULL_TREE
);
218 gfc_conv_descriptor_offset_get (tree desc
)
220 return gfc_conv_descriptor_offset (desc
);
224 gfc_conv_descriptor_offset_set (stmtblock_t
*block
, tree desc
,
227 tree t
= gfc_conv_descriptor_offset (desc
);
228 gfc_add_modify (block
, t
, fold_convert (TREE_TYPE (t
), value
));
233 gfc_conv_descriptor_dtype (tree desc
)
238 type
= TREE_TYPE (desc
);
239 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
241 field
= gfc_advance_chain (TYPE_FIELDS (type
), DTYPE_FIELD
);
242 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
244 return fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
245 desc
, field
, NULL_TREE
);
250 gfc_conv_descriptor_rank (tree desc
)
255 dtype
= gfc_conv_descriptor_dtype (desc
);
256 tmp
= build_int_cst (TREE_TYPE (dtype
), GFC_DTYPE_RANK_MASK
);
257 tmp
= fold_build2_loc (input_location
, BIT_AND_EXPR
, TREE_TYPE (dtype
),
259 return fold_convert (gfc_get_int_type (gfc_default_integer_kind
), tmp
);
264 gfc_get_descriptor_dimension (tree desc
)
268 type
= TREE_TYPE (desc
);
269 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
271 field
= gfc_advance_chain (TYPE_FIELDS (type
), DIMENSION_FIELD
);
272 gcc_assert (field
!= NULL_TREE
273 && TREE_CODE (TREE_TYPE (field
)) == ARRAY_TYPE
274 && TREE_CODE (TREE_TYPE (TREE_TYPE (field
))) == RECORD_TYPE
);
276 return fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
277 desc
, field
, NULL_TREE
);
282 gfc_conv_descriptor_dimension (tree desc
, tree dim
)
286 tmp
= gfc_get_descriptor_dimension (desc
);
288 return gfc_build_array_ref (tmp
, dim
, NULL
);
293 gfc_conv_descriptor_token (tree desc
)
298 type
= TREE_TYPE (desc
);
299 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
300 gcc_assert (GFC_TYPE_ARRAY_AKIND (type
) == GFC_ARRAY_ALLOCATABLE
);
301 gcc_assert (gfc_option
.coarray
== GFC_FCOARRAY_LIB
);
302 field
= gfc_advance_chain (TYPE_FIELDS (type
), CAF_TOKEN_FIELD
);
304 /* Should be a restricted pointer - except in the finalization wrapper. */
305 gcc_assert (field
!= NULL_TREE
306 && (TREE_TYPE (field
) == prvoid_type_node
307 || TREE_TYPE (field
) == pvoid_type_node
));
309 return fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
310 desc
, field
, NULL_TREE
);
315 gfc_conv_descriptor_stride (tree desc
, tree dim
)
320 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
321 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
322 field
= gfc_advance_chain (field
, STRIDE_SUBFIELD
);
323 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
325 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
326 tmp
, field
, NULL_TREE
);
331 gfc_conv_descriptor_stride_get (tree desc
, tree dim
)
333 tree type
= TREE_TYPE (desc
);
334 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
335 if (integer_zerop (dim
)
336 && (GFC_TYPE_ARRAY_AKIND (type
) == GFC_ARRAY_ALLOCATABLE
337 ||GFC_TYPE_ARRAY_AKIND (type
) == GFC_ARRAY_ASSUMED_SHAPE_CONT
338 ||GFC_TYPE_ARRAY_AKIND (type
) == GFC_ARRAY_ASSUMED_RANK_CONT
339 ||GFC_TYPE_ARRAY_AKIND (type
) == GFC_ARRAY_POINTER_CONT
))
340 return gfc_index_one_node
;
342 return gfc_conv_descriptor_stride (desc
, dim
);
346 gfc_conv_descriptor_stride_set (stmtblock_t
*block
, tree desc
,
347 tree dim
, tree value
)
349 tree t
= gfc_conv_descriptor_stride (desc
, dim
);
350 gfc_add_modify (block
, t
, fold_convert (TREE_TYPE (t
), value
));
354 gfc_conv_descriptor_lbound (tree desc
, tree dim
)
359 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
360 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
361 field
= gfc_advance_chain (field
, LBOUND_SUBFIELD
);
362 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
364 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
365 tmp
, field
, NULL_TREE
);
370 gfc_conv_descriptor_lbound_get (tree desc
, tree dim
)
372 return gfc_conv_descriptor_lbound (desc
, dim
);
376 gfc_conv_descriptor_lbound_set (stmtblock_t
*block
, tree desc
,
377 tree dim
, tree value
)
379 tree t
= gfc_conv_descriptor_lbound (desc
, dim
);
380 gfc_add_modify (block
, t
, fold_convert (TREE_TYPE (t
), value
));
384 gfc_conv_descriptor_ubound (tree desc
, tree dim
)
389 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
390 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
391 field
= gfc_advance_chain (field
, UBOUND_SUBFIELD
);
392 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
394 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
395 tmp
, field
, NULL_TREE
);
400 gfc_conv_descriptor_ubound_get (tree desc
, tree dim
)
402 return gfc_conv_descriptor_ubound (desc
, dim
);
406 gfc_conv_descriptor_ubound_set (stmtblock_t
*block
, tree desc
,
407 tree dim
, tree value
)
409 tree t
= gfc_conv_descriptor_ubound (desc
, dim
);
410 gfc_add_modify (block
, t
, fold_convert (TREE_TYPE (t
), value
));
413 /* Build a null array descriptor constructor. */
416 gfc_build_null_descriptor (tree type
)
421 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
422 gcc_assert (DATA_FIELD
== 0);
423 field
= TYPE_FIELDS (type
);
425 /* Set a NULL data pointer. */
426 tmp
= build_constructor_single (type
, field
, null_pointer_node
);
427 TREE_CONSTANT (tmp
) = 1;
428 /* All other fields are ignored. */
434 /* Modify a descriptor such that the lbound of a given dimension is the value
435 specified. This also updates ubound and offset accordingly. */
438 gfc_conv_shift_descriptor_lbound (stmtblock_t
* block
, tree desc
,
439 int dim
, tree new_lbound
)
441 tree offs
, ubound
, lbound
, stride
;
442 tree diff
, offs_diff
;
444 new_lbound
= fold_convert (gfc_array_index_type
, new_lbound
);
446 offs
= gfc_conv_descriptor_offset_get (desc
);
447 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[dim
]);
448 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[dim
]);
449 stride
= gfc_conv_descriptor_stride_get (desc
, gfc_rank_cst
[dim
]);
451 /* Get difference (new - old) by which to shift stuff. */
452 diff
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
455 /* Shift ubound and offset accordingly. This has to be done before
456 updating the lbound, as they depend on the lbound expression! */
457 ubound
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
459 gfc_conv_descriptor_ubound_set (block
, desc
, gfc_rank_cst
[dim
], ubound
);
460 offs_diff
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
462 offs
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
464 gfc_conv_descriptor_offset_set (block
, desc
, offs
);
466 /* Finally set lbound to value we want. */
467 gfc_conv_descriptor_lbound_set (block
, desc
, gfc_rank_cst
[dim
], new_lbound
);
471 /* Cleanup those #defines. */
476 #undef DIMENSION_FIELD
477 #undef CAF_TOKEN_FIELD
478 #undef STRIDE_SUBFIELD
479 #undef LBOUND_SUBFIELD
480 #undef UBOUND_SUBFIELD
483 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
484 flags & 1 = Main loop body.
485 flags & 2 = temp copy loop. */
488 gfc_mark_ss_chain_used (gfc_ss
* ss
, unsigned flags
)
490 for (; ss
!= gfc_ss_terminator
; ss
= ss
->next
)
491 ss
->info
->useflags
= flags
;
495 /* Free a gfc_ss chain. */
498 gfc_free_ss_chain (gfc_ss
* ss
)
502 while (ss
!= gfc_ss_terminator
)
504 gcc_assert (ss
!= NULL
);
513 free_ss_info (gfc_ss_info
*ss_info
)
518 if (ss_info
->refcount
> 0)
521 gcc_assert (ss_info
->refcount
== 0);
523 switch (ss_info
->type
)
526 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
527 if (ss_info
->data
.array
.subscript
[n
])
528 gfc_free_ss_chain (ss_info
->data
.array
.subscript
[n
]);
542 gfc_free_ss (gfc_ss
* ss
)
544 free_ss_info (ss
->info
);
549 /* Creates and initializes an array type gfc_ss struct. */
552 gfc_get_array_ss (gfc_ss
*next
, gfc_expr
*expr
, int dimen
, gfc_ss_type type
)
555 gfc_ss_info
*ss_info
;
558 ss_info
= gfc_get_ss_info ();
560 ss_info
->type
= type
;
561 ss_info
->expr
= expr
;
567 for (i
= 0; i
< ss
->dimen
; i
++)
574 /* Creates and initializes a temporary type gfc_ss struct. */
577 gfc_get_temp_ss (tree type
, tree string_length
, int dimen
)
580 gfc_ss_info
*ss_info
;
583 ss_info
= gfc_get_ss_info ();
585 ss_info
->type
= GFC_SS_TEMP
;
586 ss_info
->string_length
= string_length
;
587 ss_info
->data
.temp
.type
= type
;
591 ss
->next
= gfc_ss_terminator
;
593 for (i
= 0; i
< ss
->dimen
; i
++)
600 /* Creates and initializes a scalar type gfc_ss struct. */
603 gfc_get_scalar_ss (gfc_ss
*next
, gfc_expr
*expr
)
606 gfc_ss_info
*ss_info
;
608 ss_info
= gfc_get_ss_info ();
610 ss_info
->type
= GFC_SS_SCALAR
;
611 ss_info
->expr
= expr
;
621 /* Free all the SS associated with a loop. */
624 gfc_cleanup_loop (gfc_loopinfo
* loop
)
626 gfc_loopinfo
*loop_next
, **ploop
;
631 while (ss
!= gfc_ss_terminator
)
633 gcc_assert (ss
!= NULL
);
634 next
= ss
->loop_chain
;
639 /* Remove reference to self in the parent loop. */
641 for (ploop
= &loop
->parent
->nested
; *ploop
; ploop
= &(*ploop
)->next
)
648 /* Free non-freed nested loops. */
649 for (loop
= loop
->nested
; loop
; loop
= loop_next
)
651 loop_next
= loop
->next
;
652 gfc_cleanup_loop (loop
);
659 set_ss_loop (gfc_ss
*ss
, gfc_loopinfo
*loop
)
663 for (; ss
!= gfc_ss_terminator
; ss
= ss
->next
)
667 if (ss
->info
->type
== GFC_SS_SCALAR
668 || ss
->info
->type
== GFC_SS_REFERENCE
669 || ss
->info
->type
== GFC_SS_TEMP
)
672 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
673 if (ss
->info
->data
.array
.subscript
[n
] != NULL
)
674 set_ss_loop (ss
->info
->data
.array
.subscript
[n
], loop
);
679 /* Associate a SS chain with a loop. */
682 gfc_add_ss_to_loop (gfc_loopinfo
* loop
, gfc_ss
* head
)
685 gfc_loopinfo
*nested_loop
;
687 if (head
== gfc_ss_terminator
)
690 set_ss_loop (head
, loop
);
693 for (; ss
&& ss
!= gfc_ss_terminator
; ss
= ss
->next
)
697 nested_loop
= ss
->nested_ss
->loop
;
699 /* More than one ss can belong to the same loop. Hence, we add the
700 loop to the chain only if it is different from the previously
701 added one, to avoid duplicate nested loops. */
702 if (nested_loop
!= loop
->nested
)
704 gcc_assert (nested_loop
->parent
== NULL
);
705 nested_loop
->parent
= loop
;
707 gcc_assert (nested_loop
->next
== NULL
);
708 nested_loop
->next
= loop
->nested
;
709 loop
->nested
= nested_loop
;
712 gcc_assert (nested_loop
->parent
== loop
);
715 if (ss
->next
== gfc_ss_terminator
)
716 ss
->loop_chain
= loop
->ss
;
718 ss
->loop_chain
= ss
->next
;
720 gcc_assert (ss
== gfc_ss_terminator
);
725 /* Generate an initializer for a static pointer or allocatable array. */
728 gfc_trans_static_array_pointer (gfc_symbol
* sym
)
732 gcc_assert (TREE_STATIC (sym
->backend_decl
));
733 /* Just zero the data member. */
734 type
= TREE_TYPE (sym
->backend_decl
);
735 DECL_INITIAL (sym
->backend_decl
) = gfc_build_null_descriptor (type
);
739 /* If the bounds of SE's loop have not yet been set, see if they can be
740 determined from array spec AS, which is the array spec of a called
741 function. MAPPING maps the callee's dummy arguments to the values
742 that the caller is passing. Add any initialization and finalization
746 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping
* mapping
,
747 gfc_se
* se
, gfc_array_spec
* as
)
749 int n
, dim
, total_dim
;
758 if (!as
|| as
->type
!= AS_EXPLICIT
)
761 for (ss
= se
->ss
; ss
; ss
= ss
->parent
)
763 total_dim
+= ss
->loop
->dimen
;
764 for (n
= 0; n
< ss
->loop
->dimen
; n
++)
766 /* The bound is known, nothing to do. */
767 if (ss
->loop
->to
[n
] != NULL_TREE
)
771 gcc_assert (dim
< as
->rank
);
772 gcc_assert (ss
->loop
->dimen
<= as
->rank
);
774 /* Evaluate the lower bound. */
775 gfc_init_se (&tmpse
, NULL
);
776 gfc_apply_interface_mapping (mapping
, &tmpse
, as
->lower
[dim
]);
777 gfc_add_block_to_block (&se
->pre
, &tmpse
.pre
);
778 gfc_add_block_to_block (&se
->post
, &tmpse
.post
);
779 lower
= fold_convert (gfc_array_index_type
, tmpse
.expr
);
781 /* ...and the upper bound. */
782 gfc_init_se (&tmpse
, NULL
);
783 gfc_apply_interface_mapping (mapping
, &tmpse
, as
->upper
[dim
]);
784 gfc_add_block_to_block (&se
->pre
, &tmpse
.pre
);
785 gfc_add_block_to_block (&se
->post
, &tmpse
.post
);
786 upper
= fold_convert (gfc_array_index_type
, tmpse
.expr
);
788 /* Set the upper bound of the loop to UPPER - LOWER. */
789 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
790 gfc_array_index_type
, upper
, lower
);
791 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
792 ss
->loop
->to
[n
] = tmp
;
796 gcc_assert (total_dim
== as
->rank
);
800 /* Generate code to allocate an array temporary, or create a variable to
801 hold the data. If size is NULL, zero the descriptor so that the
802 callee will allocate the array. If DEALLOC is true, also generate code to
803 free the array afterwards.
805 If INITIAL is not NULL, it is packed using internal_pack and the result used
806 as data instead of allocating a fresh, unitialized area of memory.
808 Initialization code is added to PRE and finalization code to POST.
809 DYNAMIC is true if the caller may want to extend the array later
810 using realloc. This prevents us from putting the array on the stack. */
813 gfc_trans_allocate_array_storage (stmtblock_t
* pre
, stmtblock_t
* post
,
814 gfc_array_info
* info
, tree size
, tree nelem
,
815 tree initial
, bool dynamic
, bool dealloc
)
821 desc
= info
->descriptor
;
822 info
->offset
= gfc_index_zero_node
;
823 if (size
== NULL_TREE
|| integer_zerop (size
))
825 /* A callee allocated array. */
826 gfc_conv_descriptor_data_set (pre
, desc
, null_pointer_node
);
831 /* Allocate the temporary. */
832 onstack
= !dynamic
&& initial
== NULL_TREE
833 && (gfc_option
.flag_stack_arrays
834 || gfc_can_put_var_on_stack (size
));
838 /* Make a temporary variable to hold the data. */
839 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (nelem
),
840 nelem
, gfc_index_one_node
);
841 tmp
= gfc_evaluate_now (tmp
, pre
);
842 tmp
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
,
844 tmp
= build_array_type (gfc_get_element_type (TREE_TYPE (desc
)),
846 tmp
= gfc_create_var (tmp
, "A");
847 /* If we're here only because of -fstack-arrays we have to
848 emit a DECL_EXPR to make the gimplifier emit alloca calls. */
849 if (!gfc_can_put_var_on_stack (size
))
850 gfc_add_expr_to_block (pre
,
851 fold_build1_loc (input_location
,
852 DECL_EXPR
, TREE_TYPE (tmp
),
854 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
855 gfc_conv_descriptor_data_set (pre
, desc
, tmp
);
859 /* Allocate memory to hold the data or call internal_pack. */
860 if (initial
== NULL_TREE
)
862 tmp
= gfc_call_malloc (pre
, NULL
, size
);
863 tmp
= gfc_evaluate_now (tmp
, pre
);
870 stmtblock_t do_copying
;
872 tmp
= TREE_TYPE (initial
); /* Pointer to descriptor. */
873 gcc_assert (TREE_CODE (tmp
) == POINTER_TYPE
);
874 tmp
= TREE_TYPE (tmp
); /* The descriptor itself. */
875 tmp
= gfc_get_element_type (tmp
);
876 gcc_assert (tmp
== gfc_get_element_type (TREE_TYPE (desc
)));
877 packed
= gfc_create_var (build_pointer_type (tmp
), "data");
879 tmp
= build_call_expr_loc (input_location
,
880 gfor_fndecl_in_pack
, 1, initial
);
881 tmp
= fold_convert (TREE_TYPE (packed
), tmp
);
882 gfc_add_modify (pre
, packed
, tmp
);
884 tmp
= build_fold_indirect_ref_loc (input_location
,
886 source_data
= gfc_conv_descriptor_data_get (tmp
);
888 /* internal_pack may return source->data without any allocation
889 or copying if it is already packed. If that's the case, we
890 need to allocate and copy manually. */
892 gfc_start_block (&do_copying
);
893 tmp
= gfc_call_malloc (&do_copying
, NULL
, size
);
894 tmp
= fold_convert (TREE_TYPE (packed
), tmp
);
895 gfc_add_modify (&do_copying
, packed
, tmp
);
896 tmp
= gfc_build_memcpy_call (packed
, source_data
, size
);
897 gfc_add_expr_to_block (&do_copying
, tmp
);
899 was_packed
= fold_build2_loc (input_location
, EQ_EXPR
,
900 boolean_type_node
, packed
,
902 tmp
= gfc_finish_block (&do_copying
);
903 tmp
= build3_v (COND_EXPR
, was_packed
, tmp
,
904 build_empty_stmt (input_location
));
905 gfc_add_expr_to_block (pre
, tmp
);
907 tmp
= fold_convert (pvoid_type_node
, packed
);
910 gfc_conv_descriptor_data_set (pre
, desc
, tmp
);
913 info
->data
= gfc_conv_descriptor_data_get (desc
);
915 /* The offset is zero because we create temporaries with a zero
917 gfc_conv_descriptor_offset_set (pre
, desc
, gfc_index_zero_node
);
919 if (dealloc
&& !onstack
)
921 /* Free the temporary. */
922 tmp
= gfc_conv_descriptor_data_get (desc
);
923 tmp
= gfc_call_free (fold_convert (pvoid_type_node
, tmp
));
924 gfc_add_expr_to_block (post
, tmp
);
929 /* Get the scalarizer array dimension corresponding to actual array dimension
932 For example, if SS represents the array ref a(1,:,:,1), it is a
933 bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1,
934 and 1 for ARRAY_DIM=2.
935 If SS represents transpose(a(:,1,1,:)), it is again a bidimensional
936 scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for
938 If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer
939 array. If called on the inner ss, the result would be respectively 0,1,2 for
940 ARRAY_DIM=0,1,2. If called on the outer ss, the result would be 0,1
941 for ARRAY_DIM=1,2. */
944 get_scalarizer_dim_for_array_dim (gfc_ss
*ss
, int array_dim
)
951 for (; ss
; ss
= ss
->parent
)
952 for (n
= 0; n
< ss
->dimen
; n
++)
953 if (ss
->dim
[n
] < array_dim
)
956 return array_ref_dim
;
961 innermost_ss (gfc_ss
*ss
)
963 while (ss
->nested_ss
!= NULL
)
971 /* Get the array reference dimension corresponding to the given loop dimension.
972 It is different from the true array dimension given by the dim array in
973 the case of a partial array reference (i.e. a(:,:,1,:) for example)
974 It is different from the loop dimension in the case of a transposed array.
978 get_array_ref_dim_for_loop_dim (gfc_ss
*ss
, int loop_dim
)
980 return get_scalarizer_dim_for_array_dim (innermost_ss (ss
),
985 /* Generate code to create and initialize the descriptor for a temporary
986 array. This is used for both temporaries needed by the scalarizer, and
987 functions returning arrays. Adjusts the loop variables to be
988 zero-based, and calculates the loop bounds for callee allocated arrays.
989 Allocate the array unless it's callee allocated (we have a callee
990 allocated array if 'callee_alloc' is true, or if loop->to[n] is
991 NULL_TREE for any n). Also fills in the descriptor, data and offset
992 fields of info if known. Returns the size of the array, or NULL for a
993 callee allocated array.
995 'eltype' == NULL signals that the temporary should be a class object.
996 The 'initial' expression is used to obtain the size of the dynamic
997 type; otherwise the allocation and initialisation proceeds as for any
1000 PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
1001 gfc_trans_allocate_array_storage. */
1004 gfc_trans_create_temp_array (stmtblock_t
* pre
, stmtblock_t
* post
, gfc_ss
* ss
,
1005 tree eltype
, tree initial
, bool dynamic
,
1006 bool dealloc
, bool callee_alloc
, locus
* where
)
1010 gfc_array_info
*info
;
1011 tree from
[GFC_MAX_DIMENSIONS
], to
[GFC_MAX_DIMENSIONS
];
1019 tree class_expr
= NULL_TREE
;
1020 int n
, dim
, tmp_dim
;
1023 /* This signals a class array for which we need the size of the
1024 dynamic type. Generate an eltype and then the class expression. */
1025 if (eltype
== NULL_TREE
&& initial
)
1027 gcc_assert (POINTER_TYPE_P (TREE_TYPE (initial
)));
1028 class_expr
= build_fold_indirect_ref_loc (input_location
, initial
);
1029 eltype
= TREE_TYPE (class_expr
);
1030 eltype
= gfc_get_element_type (eltype
);
1031 /* Obtain the structure (class) expression. */
1032 class_expr
= TREE_OPERAND (class_expr
, 0);
1033 gcc_assert (class_expr
);
1036 memset (from
, 0, sizeof (from
));
1037 memset (to
, 0, sizeof (to
));
1039 info
= &ss
->info
->data
.array
;
1041 gcc_assert (ss
->dimen
> 0);
1042 gcc_assert (ss
->loop
->dimen
== ss
->dimen
);
1044 if (gfc_option
.warn_array_temp
&& where
)
1045 gfc_warning ("Creating array temporary at %L", where
);
1047 /* Set the lower bound to zero. */
1048 for (s
= ss
; s
; s
= s
->parent
)
1052 total_dim
+= loop
->dimen
;
1053 for (n
= 0; n
< loop
->dimen
; n
++)
1057 /* Callee allocated arrays may not have a known bound yet. */
1059 loop
->to
[n
] = gfc_evaluate_now (
1060 fold_build2_loc (input_location
, MINUS_EXPR
,
1061 gfc_array_index_type
,
1062 loop
->to
[n
], loop
->from
[n
]),
1064 loop
->from
[n
] = gfc_index_zero_node
;
1066 /* We have just changed the loop bounds, we must clear the
1067 corresponding specloop, so that delta calculation is not skipped
1068 later in gfc_set_delta. */
1069 loop
->specloop
[n
] = NULL
;
1071 /* We are constructing the temporary's descriptor based on the loop
1072 dimensions. As the dimensions may be accessed in arbitrary order
1073 (think of transpose) the size taken from the n'th loop may not map
1074 to the n'th dimension of the array. We need to reconstruct loop
1075 infos in the right order before using it to set the descriptor
1077 tmp_dim
= get_scalarizer_dim_for_array_dim (ss
, dim
);
1078 from
[tmp_dim
] = loop
->from
[n
];
1079 to
[tmp_dim
] = loop
->to
[n
];
1081 info
->delta
[dim
] = gfc_index_zero_node
;
1082 info
->start
[dim
] = gfc_index_zero_node
;
1083 info
->end
[dim
] = gfc_index_zero_node
;
1084 info
->stride
[dim
] = gfc_index_one_node
;
1088 /* Initialize the descriptor. */
1090 gfc_get_array_type_bounds (eltype
, total_dim
, 0, from
, to
, 1,
1091 GFC_ARRAY_UNKNOWN
, true);
1092 desc
= gfc_create_var (type
, "atmp");
1093 GFC_DECL_PACKED_ARRAY (desc
) = 1;
1095 info
->descriptor
= desc
;
1096 size
= gfc_index_one_node
;
1098 /* Fill in the array dtype. */
1099 tmp
= gfc_conv_descriptor_dtype (desc
);
1100 gfc_add_modify (pre
, tmp
, gfc_get_dtype (TREE_TYPE (desc
)));
1103 Fill in the bounds and stride. This is a packed array, so:
1106 for (n = 0; n < rank; n++)
1109 delta = ubound[n] + 1 - lbound[n];
1110 size = size * delta;
1112 size = size * sizeof(element);
1115 or_expr
= NULL_TREE
;
1117 /* If there is at least one null loop->to[n], it is a callee allocated
1119 for (n
= 0; n
< total_dim
; n
++)
1120 if (to
[n
] == NULL_TREE
)
1126 if (size
== NULL_TREE
)
1127 for (s
= ss
; s
; s
= s
->parent
)
1128 for (n
= 0; n
< s
->loop
->dimen
; n
++)
1130 dim
= get_scalarizer_dim_for_array_dim (ss
, s
->dim
[n
]);
1132 /* For a callee allocated array express the loop bounds in terms
1133 of the descriptor fields. */
1134 tmp
= fold_build2_loc (input_location
,
1135 MINUS_EXPR
, gfc_array_index_type
,
1136 gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[dim
]),
1137 gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[dim
]));
1138 s
->loop
->to
[n
] = tmp
;
1142 for (n
= 0; n
< total_dim
; n
++)
1144 /* Store the stride and bound components in the descriptor. */
1145 gfc_conv_descriptor_stride_set (pre
, desc
, gfc_rank_cst
[n
], size
);
1147 gfc_conv_descriptor_lbound_set (pre
, desc
, gfc_rank_cst
[n
],
1148 gfc_index_zero_node
);
1150 gfc_conv_descriptor_ubound_set (pre
, desc
, gfc_rank_cst
[n
], to
[n
]);
1152 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
1153 gfc_array_index_type
,
1154 to
[n
], gfc_index_one_node
);
1156 /* Check whether the size for this dimension is negative. */
1157 cond
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
1158 tmp
, gfc_index_zero_node
);
1159 cond
= gfc_evaluate_now (cond
, pre
);
1164 or_expr
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1165 boolean_type_node
, or_expr
, cond
);
1167 size
= fold_build2_loc (input_location
, MULT_EXPR
,
1168 gfc_array_index_type
, size
, tmp
);
1169 size
= gfc_evaluate_now (size
, pre
);
1173 /* Get the size of the array. */
1174 if (size
&& !callee_alloc
)
1177 /* If or_expr is true, then the extent in at least one
1178 dimension is zero and the size is set to zero. */
1179 size
= fold_build3_loc (input_location
, COND_EXPR
, gfc_array_index_type
,
1180 or_expr
, gfc_index_zero_node
, size
);
1183 if (class_expr
== NULL_TREE
)
1184 elemsize
= fold_convert (gfc_array_index_type
,
1185 TYPE_SIZE_UNIT (gfc_get_element_type (type
)));
1187 elemsize
= gfc_vtable_size_get (class_expr
);
1189 size
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
1198 gfc_trans_allocate_array_storage (pre
, post
, info
, size
, nelem
, initial
,
1204 if (ss
->dimen
> ss
->loop
->temp_dim
)
1205 ss
->loop
->temp_dim
= ss
->dimen
;
1211 /* Return the number of iterations in a loop that starts at START,
1212 ends at END, and has step STEP. */
1215 gfc_get_iteration_count (tree start
, tree end
, tree step
)
1220 type
= TREE_TYPE (step
);
1221 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, type
, end
, start
);
1222 tmp
= fold_build2_loc (input_location
, FLOOR_DIV_EXPR
, type
, tmp
, step
);
1223 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, type
, tmp
,
1224 build_int_cst (type
, 1));
1225 tmp
= fold_build2_loc (input_location
, MAX_EXPR
, type
, tmp
,
1226 build_int_cst (type
, 0));
1227 return fold_convert (gfc_array_index_type
, tmp
);
1231 /* Extend the data in array DESC by EXTRA elements. */
1234 gfc_grow_array (stmtblock_t
* pblock
, tree desc
, tree extra
)
1241 if (integer_zerop (extra
))
1244 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[0]);
1246 /* Add EXTRA to the upper bound. */
1247 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
1249 gfc_conv_descriptor_ubound_set (pblock
, desc
, gfc_rank_cst
[0], tmp
);
1251 /* Get the value of the current data pointer. */
1252 arg0
= gfc_conv_descriptor_data_get (desc
);
1254 /* Calculate the new array size. */
1255 size
= TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc
)));
1256 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
1257 ubound
, gfc_index_one_node
);
1258 arg1
= fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
1259 fold_convert (size_type_node
, tmp
),
1260 fold_convert (size_type_node
, size
));
1262 /* Call the realloc() function. */
1263 tmp
= gfc_call_realloc (pblock
, arg0
, arg1
);
1264 gfc_conv_descriptor_data_set (pblock
, desc
, tmp
);
1268 /* Return true if the bounds of iterator I can only be determined
1272 gfc_iterator_has_dynamic_bounds (gfc_iterator
* i
)
1274 return (i
->start
->expr_type
!= EXPR_CONSTANT
1275 || i
->end
->expr_type
!= EXPR_CONSTANT
1276 || i
->step
->expr_type
!= EXPR_CONSTANT
);
1280 /* Split the size of constructor element EXPR into the sum of two terms,
1281 one of which can be determined at compile time and one of which must
1282 be calculated at run time. Set *SIZE to the former and return true
1283 if the latter might be nonzero. */
1286 gfc_get_array_constructor_element_size (mpz_t
* size
, gfc_expr
* expr
)
1288 if (expr
->expr_type
== EXPR_ARRAY
)
1289 return gfc_get_array_constructor_size (size
, expr
->value
.constructor
);
1290 else if (expr
->rank
> 0)
1292 /* Calculate everything at run time. */
1293 mpz_set_ui (*size
, 0);
1298 /* A single element. */
1299 mpz_set_ui (*size
, 1);
1305 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1306 of array constructor C. */
1309 gfc_get_array_constructor_size (mpz_t
* size
, gfc_constructor_base base
)
1317 mpz_set_ui (*size
, 0);
1322 for (c
= gfc_constructor_first (base
); c
; c
= gfc_constructor_next (c
))
1325 if (i
&& gfc_iterator_has_dynamic_bounds (i
))
1329 dynamic
|= gfc_get_array_constructor_element_size (&len
, c
->expr
);
1332 /* Multiply the static part of the element size by the
1333 number of iterations. */
1334 mpz_sub (val
, i
->end
->value
.integer
, i
->start
->value
.integer
);
1335 mpz_fdiv_q (val
, val
, i
->step
->value
.integer
);
1336 mpz_add_ui (val
, val
, 1);
1337 if (mpz_sgn (val
) > 0)
1338 mpz_mul (len
, len
, val
);
1340 mpz_set_ui (len
, 0);
1342 mpz_add (*size
, *size
, len
);
1351 /* Make sure offset is a variable. */
1354 gfc_put_offset_into_var (stmtblock_t
* pblock
, tree
* poffset
,
1357 /* We should have already created the offset variable. We cannot
1358 create it here because we may be in an inner scope. */
1359 gcc_assert (*offsetvar
!= NULL_TREE
);
1360 gfc_add_modify (pblock
, *offsetvar
, *poffset
);
1361 *poffset
= *offsetvar
;
1362 TREE_USED (*offsetvar
) = 1;
1366 /* Variables needed for bounds-checking. */
1367 static bool first_len
;
1368 static tree first_len_val
;
1369 static bool typespec_chararray_ctor
;
1372 gfc_trans_array_ctor_element (stmtblock_t
* pblock
, tree desc
,
1373 tree offset
, gfc_se
* se
, gfc_expr
* expr
)
1377 gfc_conv_expr (se
, expr
);
1379 /* Store the value. */
1380 tmp
= build_fold_indirect_ref_loc (input_location
,
1381 gfc_conv_descriptor_data_get (desc
));
1382 tmp
= gfc_build_array_ref (tmp
, offset
, NULL
);
1384 if (expr
->ts
.type
== BT_CHARACTER
)
1386 int i
= gfc_validate_kind (BT_CHARACTER
, expr
->ts
.kind
, false);
1389 esize
= size_in_bytes (gfc_get_element_type (TREE_TYPE (desc
)));
1390 esize
= fold_convert (gfc_charlen_type_node
, esize
);
1391 esize
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
1392 gfc_charlen_type_node
, esize
,
1393 build_int_cst (gfc_charlen_type_node
,
1394 gfc_character_kinds
[i
].bit_size
/ 8));
1396 gfc_conv_string_parameter (se
);
1397 if (POINTER_TYPE_P (TREE_TYPE (tmp
)))
1399 /* The temporary is an array of pointers. */
1400 se
->expr
= fold_convert (TREE_TYPE (tmp
), se
->expr
);
1401 gfc_add_modify (&se
->pre
, tmp
, se
->expr
);
1405 /* The temporary is an array of string values. */
1406 tmp
= gfc_build_addr_expr (gfc_get_pchar_type (expr
->ts
.kind
), tmp
);
1407 /* We know the temporary and the value will be the same length,
1408 so can use memcpy. */
1409 gfc_trans_string_copy (&se
->pre
, esize
, tmp
, expr
->ts
.kind
,
1410 se
->string_length
, se
->expr
, expr
->ts
.kind
);
1412 if ((gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
) && !typespec_chararray_ctor
)
1416 gfc_add_modify (&se
->pre
, first_len_val
,
1422 /* Verify that all constructor elements are of the same
1424 tree cond
= fold_build2_loc (input_location
, NE_EXPR
,
1425 boolean_type_node
, first_len_val
,
1427 gfc_trans_runtime_check
1428 (true, false, cond
, &se
->pre
, &expr
->where
,
1429 "Different CHARACTER lengths (%ld/%ld) in array constructor",
1430 fold_convert (long_integer_type_node
, first_len_val
),
1431 fold_convert (long_integer_type_node
, se
->string_length
));
1437 /* TODO: Should the frontend already have done this conversion? */
1438 se
->expr
= fold_convert (TREE_TYPE (tmp
), se
->expr
);
1439 gfc_add_modify (&se
->pre
, tmp
, se
->expr
);
1442 gfc_add_block_to_block (pblock
, &se
->pre
);
1443 gfc_add_block_to_block (pblock
, &se
->post
);
1447 /* Add the contents of an array to the constructor. DYNAMIC is as for
1448 gfc_trans_array_constructor_value. */
1451 gfc_trans_array_constructor_subarray (stmtblock_t
* pblock
,
1452 tree type ATTRIBUTE_UNUSED
,
1453 tree desc
, gfc_expr
* expr
,
1454 tree
* poffset
, tree
* offsetvar
,
1465 /* We need this to be a variable so we can increment it. */
1466 gfc_put_offset_into_var (pblock
, poffset
, offsetvar
);
1468 gfc_init_se (&se
, NULL
);
1470 /* Walk the array expression. */
1471 ss
= gfc_walk_expr (expr
);
1472 gcc_assert (ss
!= gfc_ss_terminator
);
1474 /* Initialize the scalarizer. */
1475 gfc_init_loopinfo (&loop
);
1476 gfc_add_ss_to_loop (&loop
, ss
);
1478 /* Initialize the loop. */
1479 gfc_conv_ss_startstride (&loop
);
1480 gfc_conv_loop_setup (&loop
, &expr
->where
);
1482 /* Make sure the constructed array has room for the new data. */
1485 /* Set SIZE to the total number of elements in the subarray. */
1486 size
= gfc_index_one_node
;
1487 for (n
= 0; n
< loop
.dimen
; n
++)
1489 tmp
= gfc_get_iteration_count (loop
.from
[n
], loop
.to
[n
],
1490 gfc_index_one_node
);
1491 size
= fold_build2_loc (input_location
, MULT_EXPR
,
1492 gfc_array_index_type
, size
, tmp
);
1495 /* Grow the constructed array by SIZE elements. */
1496 gfc_grow_array (&loop
.pre
, desc
, size
);
1499 /* Make the loop body. */
1500 gfc_mark_ss_chain_used (ss
, 1);
1501 gfc_start_scalarized_body (&loop
, &body
);
1502 gfc_copy_loopinfo_to_se (&se
, &loop
);
1505 gfc_trans_array_ctor_element (&body
, desc
, *poffset
, &se
, expr
);
1506 gcc_assert (se
.ss
== gfc_ss_terminator
);
1508 /* Increment the offset. */
1509 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
1510 *poffset
, gfc_index_one_node
);
1511 gfc_add_modify (&body
, *poffset
, tmp
);
1513 /* Finish the loop. */
1514 gfc_trans_scalarizing_loops (&loop
, &body
);
1515 gfc_add_block_to_block (&loop
.pre
, &loop
.post
);
1516 tmp
= gfc_finish_block (&loop
.pre
);
1517 gfc_add_expr_to_block (pblock
, tmp
);
1519 gfc_cleanup_loop (&loop
);
1523 /* Assign the values to the elements of an array constructor. DYNAMIC
1524 is true if descriptor DESC only contains enough data for the static
1525 size calculated by gfc_get_array_constructor_size. When true, memory
1526 for the dynamic parts must be allocated using realloc. */
1529 gfc_trans_array_constructor_value (stmtblock_t
* pblock
, tree type
,
1530 tree desc
, gfc_constructor_base base
,
1531 tree
* poffset
, tree
* offsetvar
,
1535 tree start
= NULL_TREE
;
1536 tree end
= NULL_TREE
;
1537 tree step
= NULL_TREE
;
1543 tree shadow_loopvar
= NULL_TREE
;
1544 gfc_saved_var saved_loopvar
;
1547 for (c
= gfc_constructor_first (base
); c
; c
= gfc_constructor_next (c
))
1549 /* If this is an iterator or an array, the offset must be a variable. */
1550 if ((c
->iterator
|| c
->expr
->rank
> 0) && INTEGER_CST_P (*poffset
))
1551 gfc_put_offset_into_var (pblock
, poffset
, offsetvar
);
1553 /* Shadowing the iterator avoids changing its value and saves us from
1554 keeping track of it. Further, it makes sure that there's always a
1555 backend-decl for the symbol, even if there wasn't one before,
1556 e.g. in the case of an iterator that appears in a specification
1557 expression in an interface mapping. */
1563 /* Evaluate loop bounds before substituting the loop variable
1564 in case they depend on it. Such a case is invalid, but it is
1565 not more expensive to do the right thing here.
1567 gfc_init_se (&se
, NULL
);
1568 gfc_conv_expr_val (&se
, c
->iterator
->start
);
1569 gfc_add_block_to_block (pblock
, &se
.pre
);
1570 start
= gfc_evaluate_now (se
.expr
, pblock
);
1572 gfc_init_se (&se
, NULL
);
1573 gfc_conv_expr_val (&se
, c
->iterator
->end
);
1574 gfc_add_block_to_block (pblock
, &se
.pre
);
1575 end
= gfc_evaluate_now (se
.expr
, pblock
);
1577 gfc_init_se (&se
, NULL
);
1578 gfc_conv_expr_val (&se
, c
->iterator
->step
);
1579 gfc_add_block_to_block (pblock
, &se
.pre
);
1580 step
= gfc_evaluate_now (se
.expr
, pblock
);
1582 sym
= c
->iterator
->var
->symtree
->n
.sym
;
1583 type
= gfc_typenode_for_spec (&sym
->ts
);
1585 shadow_loopvar
= gfc_create_var (type
, "shadow_loopvar");
1586 gfc_shadow_sym (sym
, shadow_loopvar
, &saved_loopvar
);
1589 gfc_start_block (&body
);
1591 if (c
->expr
->expr_type
== EXPR_ARRAY
)
1593 /* Array constructors can be nested. */
1594 gfc_trans_array_constructor_value (&body
, type
, desc
,
1595 c
->expr
->value
.constructor
,
1596 poffset
, offsetvar
, dynamic
);
1598 else if (c
->expr
->rank
> 0)
1600 gfc_trans_array_constructor_subarray (&body
, type
, desc
, c
->expr
,
1601 poffset
, offsetvar
, dynamic
);
1605 /* This code really upsets the gimplifier so don't bother for now. */
1612 while (p
&& !(p
->iterator
|| p
->expr
->expr_type
!= EXPR_CONSTANT
))
1614 p
= gfc_constructor_next (p
);
1619 /* Scalar values. */
1620 gfc_init_se (&se
, NULL
);
1621 gfc_trans_array_ctor_element (&body
, desc
, *poffset
,
1624 *poffset
= fold_build2_loc (input_location
, PLUS_EXPR
,
1625 gfc_array_index_type
,
1626 *poffset
, gfc_index_one_node
);
1630 /* Collect multiple scalar constants into a constructor. */
1631 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1635 HOST_WIDE_INT idx
= 0;
1638 /* Count the number of consecutive scalar constants. */
1639 while (p
&& !(p
->iterator
1640 || p
->expr
->expr_type
!= EXPR_CONSTANT
))
1642 gfc_init_se (&se
, NULL
);
1643 gfc_conv_constant (&se
, p
->expr
);
1645 if (c
->expr
->ts
.type
!= BT_CHARACTER
)
1646 se
.expr
= fold_convert (type
, se
.expr
);
1647 /* For constant character array constructors we build
1648 an array of pointers. */
1649 else if (POINTER_TYPE_P (type
))
1650 se
.expr
= gfc_build_addr_expr
1651 (gfc_get_pchar_type (p
->expr
->ts
.kind
),
1654 CONSTRUCTOR_APPEND_ELT (v
,
1655 build_int_cst (gfc_array_index_type
,
1659 p
= gfc_constructor_next (p
);
1662 bound
= size_int (n
- 1);
1663 /* Create an array type to hold them. */
1664 tmptype
= build_range_type (gfc_array_index_type
,
1665 gfc_index_zero_node
, bound
);
1666 tmptype
= build_array_type (type
, tmptype
);
1668 init
= build_constructor (tmptype
, v
);
1669 TREE_CONSTANT (init
) = 1;
1670 TREE_STATIC (init
) = 1;
1671 /* Create a static variable to hold the data. */
1672 tmp
= gfc_create_var (tmptype
, "data");
1673 TREE_STATIC (tmp
) = 1;
1674 TREE_CONSTANT (tmp
) = 1;
1675 TREE_READONLY (tmp
) = 1;
1676 DECL_INITIAL (tmp
) = init
;
1679 /* Use BUILTIN_MEMCPY to assign the values. */
1680 tmp
= gfc_conv_descriptor_data_get (desc
);
1681 tmp
= build_fold_indirect_ref_loc (input_location
,
1683 tmp
= gfc_build_array_ref (tmp
, *poffset
, NULL
);
1684 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
1685 init
= gfc_build_addr_expr (NULL_TREE
, init
);
1687 size
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
));
1688 bound
= build_int_cst (size_type_node
, n
* size
);
1689 tmp
= build_call_expr_loc (input_location
,
1690 builtin_decl_explicit (BUILT_IN_MEMCPY
),
1691 3, tmp
, init
, bound
);
1692 gfc_add_expr_to_block (&body
, tmp
);
1694 *poffset
= fold_build2_loc (input_location
, PLUS_EXPR
,
1695 gfc_array_index_type
, *poffset
,
1696 build_int_cst (gfc_array_index_type
, n
));
1698 if (!INTEGER_CST_P (*poffset
))
1700 gfc_add_modify (&body
, *offsetvar
, *poffset
);
1701 *poffset
= *offsetvar
;
1705 /* The frontend should already have done any expansions
1709 /* Pass the code as is. */
1710 tmp
= gfc_finish_block (&body
);
1711 gfc_add_expr_to_block (pblock
, tmp
);
1715 /* Build the implied do-loop. */
1716 stmtblock_t implied_do_block
;
1722 loopbody
= gfc_finish_block (&body
);
1724 /* Create a new block that holds the implied-do loop. A temporary
1725 loop-variable is used. */
1726 gfc_start_block(&implied_do_block
);
1728 /* Initialize the loop. */
1729 gfc_add_modify (&implied_do_block
, shadow_loopvar
, start
);
1731 /* If this array expands dynamically, and the number of iterations
1732 is not constant, we won't have allocated space for the static
1733 part of C->EXPR's size. Do that now. */
1734 if (dynamic
&& gfc_iterator_has_dynamic_bounds (c
->iterator
))
1736 /* Get the number of iterations. */
1737 tmp
= gfc_get_iteration_count (shadow_loopvar
, end
, step
);
1739 /* Get the static part of C->EXPR's size. */
1740 gfc_get_array_constructor_element_size (&size
, c
->expr
);
1741 tmp2
= gfc_conv_mpz_to_tree (size
, gfc_index_integer_kind
);
1743 /* Grow the array by TMP * TMP2 elements. */
1744 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
1745 gfc_array_index_type
, tmp
, tmp2
);
1746 gfc_grow_array (&implied_do_block
, desc
, tmp
);
1749 /* Generate the loop body. */
1750 exit_label
= gfc_build_label_decl (NULL_TREE
);
1751 gfc_start_block (&body
);
1753 /* Generate the exit condition. Depending on the sign of
1754 the step variable we have to generate the correct
1756 tmp
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
1757 step
, build_int_cst (TREE_TYPE (step
), 0));
1758 cond
= fold_build3_loc (input_location
, COND_EXPR
,
1759 boolean_type_node
, tmp
,
1760 fold_build2_loc (input_location
, GT_EXPR
,
1761 boolean_type_node
, shadow_loopvar
, end
),
1762 fold_build2_loc (input_location
, LT_EXPR
,
1763 boolean_type_node
, shadow_loopvar
, end
));
1764 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1765 TREE_USED (exit_label
) = 1;
1766 tmp
= build3_v (COND_EXPR
, cond
, tmp
,
1767 build_empty_stmt (input_location
));
1768 gfc_add_expr_to_block (&body
, tmp
);
1770 /* The main loop body. */
1771 gfc_add_expr_to_block (&body
, loopbody
);
1773 /* Increase loop variable by step. */
1774 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
1775 TREE_TYPE (shadow_loopvar
), shadow_loopvar
,
1777 gfc_add_modify (&body
, shadow_loopvar
, tmp
);
1779 /* Finish the loop. */
1780 tmp
= gfc_finish_block (&body
);
1781 tmp
= build1_v (LOOP_EXPR
, tmp
);
1782 gfc_add_expr_to_block (&implied_do_block
, tmp
);
1784 /* Add the exit label. */
1785 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1786 gfc_add_expr_to_block (&implied_do_block
, tmp
);
1788 /* Finish the implied-do loop. */
1789 tmp
= gfc_finish_block(&implied_do_block
);
1790 gfc_add_expr_to_block(pblock
, tmp
);
1792 gfc_restore_sym (c
->iterator
->var
->symtree
->n
.sym
, &saved_loopvar
);
1799 /* A catch-all to obtain the string length for anything that is not
1800 a substring of non-constant length, a constant, array or variable. */
1803 get_array_ctor_all_strlen (stmtblock_t
*block
, gfc_expr
*e
, tree
*len
)
1807 /* Don't bother if we already know the length is a constant. */
1808 if (*len
&& INTEGER_CST_P (*len
))
1811 if (!e
->ref
&& e
->ts
.u
.cl
&& e
->ts
.u
.cl
->length
1812 && e
->ts
.u
.cl
->length
->expr_type
== EXPR_CONSTANT
)
1815 gfc_conv_const_charlen (e
->ts
.u
.cl
);
1816 *len
= e
->ts
.u
.cl
->backend_decl
;
1820 /* Otherwise, be brutal even if inefficient. */
1821 gfc_init_se (&se
, NULL
);
1823 /* No function call, in case of side effects. */
1824 se
.no_function_call
= 1;
1826 gfc_conv_expr (&se
, e
);
1828 gfc_conv_expr_descriptor (&se
, e
);
1830 /* Fix the value. */
1831 *len
= gfc_evaluate_now (se
.string_length
, &se
.pre
);
1833 gfc_add_block_to_block (block
, &se
.pre
);
1834 gfc_add_block_to_block (block
, &se
.post
);
1836 e
->ts
.u
.cl
->backend_decl
= *len
;
1841 /* Figure out the string length of a variable reference expression.
1842 Used by get_array_ctor_strlen. */
1845 get_array_ctor_var_strlen (stmtblock_t
*block
, gfc_expr
* expr
, tree
* len
)
1851 /* Don't bother if we already know the length is a constant. */
1852 if (*len
&& INTEGER_CST_P (*len
))
1855 ts
= &expr
->symtree
->n
.sym
->ts
;
1856 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
1861 /* Array references don't change the string length. */
1865 /* Use the length of the component. */
1866 ts
= &ref
->u
.c
.component
->ts
;
1870 if (ref
->u
.ss
.start
->expr_type
!= EXPR_CONSTANT
1871 || ref
->u
.ss
.end
->expr_type
!= EXPR_CONSTANT
)
1873 /* Note that this might evaluate expr. */
1874 get_array_ctor_all_strlen (block
, expr
, len
);
1877 mpz_init_set_ui (char_len
, 1);
1878 mpz_add (char_len
, char_len
, ref
->u
.ss
.end
->value
.integer
);
1879 mpz_sub (char_len
, char_len
, ref
->u
.ss
.start
->value
.integer
);
1880 *len
= gfc_conv_mpz_to_tree (char_len
, gfc_default_integer_kind
);
1881 *len
= convert (gfc_charlen_type_node
, *len
);
1882 mpz_clear (char_len
);
1890 *len
= ts
->u
.cl
->backend_decl
;
1894 /* Figure out the string length of a character array constructor.
1895 If len is NULL, don't calculate the length; this happens for recursive calls
1896 when a sub-array-constructor is an element but not at the first position,
1897 so when we're not interested in the length.
1898 Returns TRUE if all elements are character constants. */
1901 get_array_ctor_strlen (stmtblock_t
*block
, gfc_constructor_base base
, tree
* len
)
1908 if (gfc_constructor_first (base
) == NULL
)
1911 *len
= build_int_cstu (gfc_charlen_type_node
, 0);
1915 /* Loop over all constructor elements to find out is_const, but in len we
1916 want to store the length of the first, not the last, element. We can
1917 of course exit the loop as soon as is_const is found to be false. */
1918 for (c
= gfc_constructor_first (base
);
1919 c
&& is_const
; c
= gfc_constructor_next (c
))
1921 switch (c
->expr
->expr_type
)
1924 if (len
&& !(*len
&& INTEGER_CST_P (*len
)))
1925 *len
= build_int_cstu (gfc_charlen_type_node
,
1926 c
->expr
->value
.character
.length
);
1930 if (!get_array_ctor_strlen (block
, c
->expr
->value
.constructor
, len
))
1937 get_array_ctor_var_strlen (block
, c
->expr
, len
);
1943 get_array_ctor_all_strlen (block
, c
->expr
, len
);
1947 /* After the first iteration, we don't want the length modified. */
1954 /* Check whether the array constructor C consists entirely of constant
1955 elements, and if so returns the number of those elements, otherwise
1956 return zero. Note, an empty or NULL array constructor returns zero. */
1958 unsigned HOST_WIDE_INT
1959 gfc_constant_array_constructor_p (gfc_constructor_base base
)
1961 unsigned HOST_WIDE_INT nelem
= 0;
1963 gfc_constructor
*c
= gfc_constructor_first (base
);
1967 || c
->expr
->rank
> 0
1968 || c
->expr
->expr_type
!= EXPR_CONSTANT
)
1970 c
= gfc_constructor_next (c
);
1977 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1978 and the tree type of it's elements, TYPE, return a static constant
1979 variable that is compile-time initialized. */
1982 gfc_build_constant_array_constructor (gfc_expr
* expr
, tree type
)
1984 tree tmptype
, init
, tmp
;
1985 HOST_WIDE_INT nelem
;
1990 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1992 /* First traverse the constructor list, converting the constants
1993 to tree to build an initializer. */
1995 c
= gfc_constructor_first (expr
->value
.constructor
);
1998 gfc_init_se (&se
, NULL
);
1999 gfc_conv_constant (&se
, c
->expr
);
2000 if (c
->expr
->ts
.type
!= BT_CHARACTER
)
2001 se
.expr
= fold_convert (type
, se
.expr
);
2002 else if (POINTER_TYPE_P (type
))
2003 se
.expr
= gfc_build_addr_expr (gfc_get_pchar_type (c
->expr
->ts
.kind
),
2005 CONSTRUCTOR_APPEND_ELT (v
, build_int_cst (gfc_array_index_type
, nelem
),
2007 c
= gfc_constructor_next (c
);
2011 /* Next determine the tree type for the array. We use the gfortran
2012 front-end's gfc_get_nodesc_array_type in order to create a suitable
2013 GFC_ARRAY_TYPE_P that may be used by the scalarizer. */
2015 memset (&as
, 0, sizeof (gfc_array_spec
));
2017 as
.rank
= expr
->rank
;
2018 as
.type
= AS_EXPLICIT
;
2021 as
.lower
[0] = gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 0);
2022 as
.upper
[0] = gfc_get_int_expr (gfc_default_integer_kind
,
2026 for (i
= 0; i
< expr
->rank
; i
++)
2028 int tmp
= (int) mpz_get_si (expr
->shape
[i
]);
2029 as
.lower
[i
] = gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 0);
2030 as
.upper
[i
] = gfc_get_int_expr (gfc_default_integer_kind
,
2034 tmptype
= gfc_get_nodesc_array_type (type
, &as
, PACKED_STATIC
, true);
2036 /* as is not needed anymore. */
2037 for (i
= 0; i
< as
.rank
+ as
.corank
; i
++)
2039 gfc_free_expr (as
.lower
[i
]);
2040 gfc_free_expr (as
.upper
[i
]);
2043 init
= build_constructor (tmptype
, v
);
2045 TREE_CONSTANT (init
) = 1;
2046 TREE_STATIC (init
) = 1;
2048 tmp
= gfc_create_var (tmptype
, "A");
2049 TREE_STATIC (tmp
) = 1;
2050 TREE_CONSTANT (tmp
) = 1;
2051 TREE_READONLY (tmp
) = 1;
2052 DECL_INITIAL (tmp
) = init
;
2058 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
2059 This mostly initializes the scalarizer state info structure with the
2060 appropriate values to directly use the array created by the function
2061 gfc_build_constant_array_constructor. */
2064 trans_constant_array_constructor (gfc_ss
* ss
, tree type
)
2066 gfc_array_info
*info
;
2070 tmp
= gfc_build_constant_array_constructor (ss
->info
->expr
, type
);
2072 info
= &ss
->info
->data
.array
;
2074 info
->descriptor
= tmp
;
2075 info
->data
= gfc_build_addr_expr (NULL_TREE
, tmp
);
2076 info
->offset
= gfc_index_zero_node
;
2078 for (i
= 0; i
< ss
->dimen
; i
++)
2080 info
->delta
[i
] = gfc_index_zero_node
;
2081 info
->start
[i
] = gfc_index_zero_node
;
2082 info
->end
[i
] = gfc_index_zero_node
;
2083 info
->stride
[i
] = gfc_index_one_node
;
2089 get_rank (gfc_loopinfo
*loop
)
2094 for (; loop
; loop
= loop
->parent
)
2095 rank
+= loop
->dimen
;
2101 /* Helper routine of gfc_trans_array_constructor to determine if the
2102 bounds of the loop specified by LOOP are constant and simple enough
2103 to use with trans_constant_array_constructor. Returns the
2104 iteration count of the loop if suitable, and NULL_TREE otherwise. */
2107 constant_array_constructor_loop_size (gfc_loopinfo
* l
)
2110 tree size
= gfc_index_one_node
;
2114 total_dim
= get_rank (l
);
2116 for (loop
= l
; loop
; loop
= loop
->parent
)
2118 for (i
= 0; i
< loop
->dimen
; i
++)
2120 /* If the bounds aren't constant, return NULL_TREE. */
2121 if (!INTEGER_CST_P (loop
->from
[i
]) || !INTEGER_CST_P (loop
->to
[i
]))
2123 if (!integer_zerop (loop
->from
[i
]))
2125 /* Only allow nonzero "from" in one-dimensional arrays. */
2128 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2129 gfc_array_index_type
,
2130 loop
->to
[i
], loop
->from
[i
]);
2134 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
2135 gfc_array_index_type
, tmp
, gfc_index_one_node
);
2136 size
= fold_build2_loc (input_location
, MULT_EXPR
,
2137 gfc_array_index_type
, size
, tmp
);
2146 get_loop_upper_bound_for_array (gfc_ss
*array
, int array_dim
)
2151 gcc_assert (array
->nested_ss
== NULL
);
2153 for (ss
= array
; ss
; ss
= ss
->parent
)
2154 for (n
= 0; n
< ss
->loop
->dimen
; n
++)
2155 if (array_dim
== get_array_ref_dim_for_loop_dim (ss
, n
))
2156 return &(ss
->loop
->to
[n
]);
2162 static gfc_loopinfo
*
2163 outermost_loop (gfc_loopinfo
* loop
)
2165 while (loop
->parent
!= NULL
)
2166 loop
= loop
->parent
;
2172 /* Array constructors are handled by constructing a temporary, then using that
2173 within the scalarization loop. This is not optimal, but seems by far the
2177 trans_array_constructor (gfc_ss
* ss
, locus
* where
)
2179 gfc_constructor_base c
;
2187 bool old_first_len
, old_typespec_chararray_ctor
;
2188 tree old_first_len_val
;
2189 gfc_loopinfo
*loop
, *outer_loop
;
2190 gfc_ss_info
*ss_info
;
2194 /* Save the old values for nested checking. */
2195 old_first_len
= first_len
;
2196 old_first_len_val
= first_len_val
;
2197 old_typespec_chararray_ctor
= typespec_chararray_ctor
;
2200 outer_loop
= outermost_loop (loop
);
2202 expr
= ss_info
->expr
;
2204 /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2205 typespec was given for the array constructor. */
2206 typespec_chararray_ctor
= (expr
->ts
.u
.cl
2207 && expr
->ts
.u
.cl
->length_from_typespec
);
2209 if ((gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
2210 && expr
->ts
.type
== BT_CHARACTER
&& !typespec_chararray_ctor
)
2212 first_len_val
= gfc_create_var (gfc_charlen_type_node
, "len");
2216 gcc_assert (ss
->dimen
== ss
->loop
->dimen
);
2218 c
= expr
->value
.constructor
;
2219 if (expr
->ts
.type
== BT_CHARACTER
)
2223 /* get_array_ctor_strlen walks the elements of the constructor, if a
2224 typespec was given, we already know the string length and want the one
2226 if (typespec_chararray_ctor
&& expr
->ts
.u
.cl
->length
2227 && expr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2231 const_string
= false;
2232 gfc_init_se (&length_se
, NULL
);
2233 gfc_conv_expr_type (&length_se
, expr
->ts
.u
.cl
->length
,
2234 gfc_charlen_type_node
);
2235 ss_info
->string_length
= length_se
.expr
;
2236 gfc_add_block_to_block (&outer_loop
->pre
, &length_se
.pre
);
2237 gfc_add_block_to_block (&outer_loop
->post
, &length_se
.post
);
2240 const_string
= get_array_ctor_strlen (&outer_loop
->pre
, c
,
2241 &ss_info
->string_length
);
2243 /* Complex character array constructors should have been taken care of
2244 and not end up here. */
2245 gcc_assert (ss_info
->string_length
);
2247 expr
->ts
.u
.cl
->backend_decl
= ss_info
->string_length
;
2249 type
= gfc_get_character_type_len (expr
->ts
.kind
, ss_info
->string_length
);
2251 type
= build_pointer_type (type
);
2254 type
= gfc_typenode_for_spec (&expr
->ts
);
2256 /* See if the constructor determines the loop bounds. */
2259 loop_ubound0
= get_loop_upper_bound_for_array (ss
, 0);
2261 if (expr
->shape
&& get_rank (loop
) > 1 && *loop_ubound0
== NULL_TREE
)
2263 /* We have a multidimensional parameter. */
2264 for (s
= ss
; s
; s
= s
->parent
)
2267 for (n
= 0; n
< s
->loop
->dimen
; n
++)
2269 s
->loop
->from
[n
] = gfc_index_zero_node
;
2270 s
->loop
->to
[n
] = gfc_conv_mpz_to_tree (expr
->shape
[s
->dim
[n
]],
2271 gfc_index_integer_kind
);
2272 s
->loop
->to
[n
] = fold_build2_loc (input_location
, MINUS_EXPR
,
2273 gfc_array_index_type
,
2275 gfc_index_one_node
);
2280 if (*loop_ubound0
== NULL_TREE
)
2284 /* We should have a 1-dimensional, zero-based loop. */
2285 gcc_assert (loop
->parent
== NULL
&& loop
->nested
== NULL
);
2286 gcc_assert (loop
->dimen
== 1);
2287 gcc_assert (integer_zerop (loop
->from
[0]));
2289 /* Split the constructor size into a static part and a dynamic part.
2290 Allocate the static size up-front and record whether the dynamic
2291 size might be nonzero. */
2293 dynamic
= gfc_get_array_constructor_size (&size
, c
);
2294 mpz_sub_ui (size
, size
, 1);
2295 loop
->to
[0] = gfc_conv_mpz_to_tree (size
, gfc_index_integer_kind
);
2299 /* Special case constant array constructors. */
2302 unsigned HOST_WIDE_INT nelem
= gfc_constant_array_constructor_p (c
);
2305 tree size
= constant_array_constructor_loop_size (loop
);
2306 if (size
&& compare_tree_int (size
, nelem
) == 0)
2308 trans_constant_array_constructor (ss
, type
);
2314 gfc_trans_create_temp_array (&outer_loop
->pre
, &outer_loop
->post
, ss
, type
,
2315 NULL_TREE
, dynamic
, true, false, where
);
2317 desc
= ss_info
->data
.array
.descriptor
;
2318 offset
= gfc_index_zero_node
;
2319 offsetvar
= gfc_create_var_np (gfc_array_index_type
, "offset");
2320 TREE_NO_WARNING (offsetvar
) = 1;
2321 TREE_USED (offsetvar
) = 0;
2322 gfc_trans_array_constructor_value (&outer_loop
->pre
, type
, desc
, c
,
2323 &offset
, &offsetvar
, dynamic
);
2325 /* If the array grows dynamically, the upper bound of the loop variable
2326 is determined by the array's final upper bound. */
2329 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2330 gfc_array_index_type
,
2331 offsetvar
, gfc_index_one_node
);
2332 tmp
= gfc_evaluate_now (tmp
, &outer_loop
->pre
);
2333 gfc_conv_descriptor_ubound_set (&loop
->pre
, desc
, gfc_rank_cst
[0], tmp
);
2334 if (*loop_ubound0
&& TREE_CODE (*loop_ubound0
) == VAR_DECL
)
2335 gfc_add_modify (&outer_loop
->pre
, *loop_ubound0
, tmp
);
2337 *loop_ubound0
= tmp
;
2340 if (TREE_USED (offsetvar
))
2341 pushdecl (offsetvar
);
2343 gcc_assert (INTEGER_CST_P (offset
));
2346 /* Disable bound checking for now because it's probably broken. */
2347 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
2354 /* Restore old values of globals. */
2355 first_len
= old_first_len
;
2356 first_len_val
= old_first_len_val
;
2357 typespec_chararray_ctor
= old_typespec_chararray_ctor
;
2361 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2362 called after evaluating all of INFO's vector dimensions. Go through
2363 each such vector dimension and see if we can now fill in any missing
2367 set_vector_loop_bounds (gfc_ss
* ss
)
2369 gfc_loopinfo
*loop
, *outer_loop
;
2370 gfc_array_info
*info
;
2378 outer_loop
= outermost_loop (ss
->loop
);
2380 info
= &ss
->info
->data
.array
;
2382 for (; ss
; ss
= ss
->parent
)
2386 for (n
= 0; n
< loop
->dimen
; n
++)
2389 if (info
->ref
->u
.ar
.dimen_type
[dim
] != DIMEN_VECTOR
2390 || loop
->to
[n
] != NULL
)
2393 /* Loop variable N indexes vector dimension DIM, and we don't
2394 yet know the upper bound of loop variable N. Set it to the
2395 difference between the vector's upper and lower bounds. */
2396 gcc_assert (loop
->from
[n
] == gfc_index_zero_node
);
2397 gcc_assert (info
->subscript
[dim
]
2398 && info
->subscript
[dim
]->info
->type
== GFC_SS_VECTOR
);
2400 gfc_init_se (&se
, NULL
);
2401 desc
= info
->subscript
[dim
]->info
->data
.array
.descriptor
;
2402 zero
= gfc_rank_cst
[0];
2403 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2404 gfc_array_index_type
,
2405 gfc_conv_descriptor_ubound_get (desc
, zero
),
2406 gfc_conv_descriptor_lbound_get (desc
, zero
));
2407 tmp
= gfc_evaluate_now (tmp
, &outer_loop
->pre
);
2414 /* Add the pre and post chains for all the scalar expressions in a SS chain
2415 to loop. This is called after the loop parameters have been calculated,
2416 but before the actual scalarizing loops. */
2419 gfc_add_loop_ss_code (gfc_loopinfo
* loop
, gfc_ss
* ss
, bool subscript
,
2422 gfc_loopinfo
*nested_loop
, *outer_loop
;
2424 gfc_ss_info
*ss_info
;
2425 gfc_array_info
*info
;
2429 /* Don't evaluate the arguments for realloc_lhs_loop_for_fcn_call; otherwise,
2430 arguments could get evaluated multiple times. */
2431 if (ss
->is_alloc_lhs
)
2434 outer_loop
= outermost_loop (loop
);
2436 /* TODO: This can generate bad code if there are ordering dependencies,
2437 e.g., a callee allocated function and an unknown size constructor. */
2438 gcc_assert (ss
!= NULL
);
2440 for (; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
2444 /* Cross loop arrays are handled from within the most nested loop. */
2445 if (ss
->nested_ss
!= NULL
)
2449 expr
= ss_info
->expr
;
2450 info
= &ss_info
->data
.array
;
2452 switch (ss_info
->type
)
2455 /* Scalar expression. Evaluate this now. This includes elemental
2456 dimension indices, but not array section bounds. */
2457 gfc_init_se (&se
, NULL
);
2458 gfc_conv_expr (&se
, expr
);
2459 gfc_add_block_to_block (&outer_loop
->pre
, &se
.pre
);
2461 if (expr
->ts
.type
!= BT_CHARACTER
)
2463 /* Move the evaluation of scalar expressions outside the
2464 scalarization loop, except for WHERE assignments. */
2466 se
.expr
= convert(gfc_array_index_type
, se
.expr
);
2467 if (!ss_info
->where
)
2468 se
.expr
= gfc_evaluate_now (se
.expr
, &outer_loop
->pre
);
2469 gfc_add_block_to_block (&outer_loop
->pre
, &se
.post
);
2472 gfc_add_block_to_block (&outer_loop
->post
, &se
.post
);
2474 ss_info
->data
.scalar
.value
= se
.expr
;
2475 ss_info
->string_length
= se
.string_length
;
2478 case GFC_SS_REFERENCE
:
2479 /* Scalar argument to elemental procedure. */
2480 gfc_init_se (&se
, NULL
);
2481 if (ss_info
->can_be_null_ref
)
2483 /* If the actual argument can be absent (in other words, it can
2484 be a NULL reference), don't try to evaluate it; pass instead
2485 the reference directly. */
2486 gfc_conv_expr_reference (&se
, expr
);
2490 /* Otherwise, evaluate the argument outside the loop and pass
2491 a reference to the value. */
2492 gfc_conv_expr (&se
, expr
);
2494 gfc_add_block_to_block (&outer_loop
->pre
, &se
.pre
);
2495 gfc_add_block_to_block (&outer_loop
->post
, &se
.post
);
2496 if (gfc_is_class_scalar_expr (expr
))
2497 /* This is necessary because the dynamic type will always be
2498 large than the declared type. In consequence, assigning
2499 the value to a temporary could segfault.
2500 OOP-TODO: see if this is generally correct or is the value
2501 has to be written to an allocated temporary, whose address
2502 is passed via ss_info. */
2503 ss_info
->data
.scalar
.value
= se
.expr
;
2505 ss_info
->data
.scalar
.value
= gfc_evaluate_now (se
.expr
,
2508 ss_info
->string_length
= se
.string_length
;
2511 case GFC_SS_SECTION
:
2512 /* Add the expressions for scalar and vector subscripts. */
2513 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
2514 if (info
->subscript
[n
])
2515 gfc_add_loop_ss_code (loop
, info
->subscript
[n
], true, where
);
2517 set_vector_loop_bounds (ss
);
2521 /* Get the vector's descriptor and store it in SS. */
2522 gfc_init_se (&se
, NULL
);
2523 gfc_conv_expr_descriptor (&se
, expr
);
2524 gfc_add_block_to_block (&outer_loop
->pre
, &se
.pre
);
2525 gfc_add_block_to_block (&outer_loop
->post
, &se
.post
);
2526 info
->descriptor
= se
.expr
;
2529 case GFC_SS_INTRINSIC
:
2530 gfc_add_intrinsic_ss_code (loop
, ss
);
2533 case GFC_SS_FUNCTION
:
2534 /* Array function return value. We call the function and save its
2535 result in a temporary for use inside the loop. */
2536 gfc_init_se (&se
, NULL
);
2539 gfc_conv_expr (&se
, expr
);
2540 gfc_add_block_to_block (&outer_loop
->pre
, &se
.pre
);
2541 gfc_add_block_to_block (&outer_loop
->post
, &se
.post
);
2542 ss_info
->string_length
= se
.string_length
;
2545 case GFC_SS_CONSTRUCTOR
:
2546 if (expr
->ts
.type
== BT_CHARACTER
2547 && ss_info
->string_length
== NULL
2549 && expr
->ts
.u
.cl
->length
)
2551 gfc_init_se (&se
, NULL
);
2552 gfc_conv_expr_type (&se
, expr
->ts
.u
.cl
->length
,
2553 gfc_charlen_type_node
);
2554 ss_info
->string_length
= se
.expr
;
2555 gfc_add_block_to_block (&outer_loop
->pre
, &se
.pre
);
2556 gfc_add_block_to_block (&outer_loop
->post
, &se
.post
);
2558 trans_array_constructor (ss
, where
);
2562 case GFC_SS_COMPONENT
:
2563 /* Do nothing. These are handled elsewhere. */
2572 for (nested_loop
= loop
->nested
; nested_loop
;
2573 nested_loop
= nested_loop
->next
)
2574 gfc_add_loop_ss_code (nested_loop
, nested_loop
->ss
, subscript
, where
);
2578 /* Translate expressions for the descriptor and data pointer of a SS. */
2582 gfc_conv_ss_descriptor (stmtblock_t
* block
, gfc_ss
* ss
, int base
)
2585 gfc_ss_info
*ss_info
;
2586 gfc_array_info
*info
;
2590 info
= &ss_info
->data
.array
;
2592 /* Get the descriptor for the array to be scalarized. */
2593 gcc_assert (ss_info
->expr
->expr_type
== EXPR_VARIABLE
);
2594 gfc_init_se (&se
, NULL
);
2595 se
.descriptor_only
= 1;
2596 gfc_conv_expr_lhs (&se
, ss_info
->expr
);
2597 gfc_add_block_to_block (block
, &se
.pre
);
2598 info
->descriptor
= se
.expr
;
2599 ss_info
->string_length
= se
.string_length
;
2603 /* Also the data pointer. */
2604 tmp
= gfc_conv_array_data (se
.expr
);
2605 /* If this is a variable or address of a variable we use it directly.
2606 Otherwise we must evaluate it now to avoid breaking dependency
2607 analysis by pulling the expressions for elemental array indices
2610 || (TREE_CODE (tmp
) == ADDR_EXPR
2611 && DECL_P (TREE_OPERAND (tmp
, 0)))))
2612 tmp
= gfc_evaluate_now (tmp
, block
);
2615 tmp
= gfc_conv_array_offset (se
.expr
);
2616 info
->offset
= gfc_evaluate_now (tmp
, block
);
2618 /* Make absolutely sure that the saved_offset is indeed saved
2619 so that the variable is still accessible after the loops
2621 info
->saved_offset
= info
->offset
;
2626 /* Initialize a gfc_loopinfo structure. */
2629 gfc_init_loopinfo (gfc_loopinfo
* loop
)
2633 memset (loop
, 0, sizeof (gfc_loopinfo
));
2634 gfc_init_block (&loop
->pre
);
2635 gfc_init_block (&loop
->post
);
2637 /* Initially scalarize in order and default to no loop reversal. */
2638 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
2641 loop
->reverse
[n
] = GFC_INHIBIT_REVERSE
;
2644 loop
->ss
= gfc_ss_terminator
;
2648 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2652 gfc_copy_loopinfo_to_se (gfc_se
* se
, gfc_loopinfo
* loop
)
2658 /* Return an expression for the data pointer of an array. */
2661 gfc_conv_array_data (tree descriptor
)
2665 type
= TREE_TYPE (descriptor
);
2666 if (GFC_ARRAY_TYPE_P (type
))
2668 if (TREE_CODE (type
) == POINTER_TYPE
)
2672 /* Descriptorless arrays. */
2673 return gfc_build_addr_expr (NULL_TREE
, descriptor
);
2677 return gfc_conv_descriptor_data_get (descriptor
);
2681 /* Return an expression for the base offset of an array. */
2684 gfc_conv_array_offset (tree descriptor
)
2688 type
= TREE_TYPE (descriptor
);
2689 if (GFC_ARRAY_TYPE_P (type
))
2690 return GFC_TYPE_ARRAY_OFFSET (type
);
2692 return gfc_conv_descriptor_offset_get (descriptor
);
2696 /* Get an expression for the array stride. */
2699 gfc_conv_array_stride (tree descriptor
, int dim
)
2704 type
= TREE_TYPE (descriptor
);
2706 /* For descriptorless arrays use the array size. */
2707 tmp
= GFC_TYPE_ARRAY_STRIDE (type
, dim
);
2708 if (tmp
!= NULL_TREE
)
2711 tmp
= gfc_conv_descriptor_stride_get (descriptor
, gfc_rank_cst
[dim
]);
2716 /* Like gfc_conv_array_stride, but for the lower bound. */
2719 gfc_conv_array_lbound (tree descriptor
, int dim
)
2724 type
= TREE_TYPE (descriptor
);
2726 tmp
= GFC_TYPE_ARRAY_LBOUND (type
, dim
);
2727 if (tmp
!= NULL_TREE
)
2730 tmp
= gfc_conv_descriptor_lbound_get (descriptor
, gfc_rank_cst
[dim
]);
2735 /* Like gfc_conv_array_stride, but for the upper bound. */
2738 gfc_conv_array_ubound (tree descriptor
, int dim
)
2743 type
= TREE_TYPE (descriptor
);
2745 tmp
= GFC_TYPE_ARRAY_UBOUND (type
, dim
);
2746 if (tmp
!= NULL_TREE
)
2749 /* This should only ever happen when passing an assumed shape array
2750 as an actual parameter. The value will never be used. */
2751 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor
)))
2752 return gfc_index_zero_node
;
2754 tmp
= gfc_conv_descriptor_ubound_get (descriptor
, gfc_rank_cst
[dim
]);
2759 /* Generate code to perform an array index bound check. */
2762 trans_array_bound_check (gfc_se
* se
, gfc_ss
*ss
, tree index
, int n
,
2763 locus
* where
, bool check_upper
)
2766 tree tmp_lo
, tmp_up
;
2769 const char * name
= NULL
;
2771 if (!(gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
))
2774 descriptor
= ss
->info
->data
.array
.descriptor
;
2776 index
= gfc_evaluate_now (index
, &se
->pre
);
2778 /* We find a name for the error message. */
2779 name
= ss
->info
->expr
->symtree
->n
.sym
->name
;
2780 gcc_assert (name
!= NULL
);
2782 if (TREE_CODE (descriptor
) == VAR_DECL
)
2783 name
= IDENTIFIER_POINTER (DECL_NAME (descriptor
));
2785 /* If upper bound is present, include both bounds in the error message. */
2788 tmp_lo
= gfc_conv_array_lbound (descriptor
, n
);
2789 tmp_up
= gfc_conv_array_ubound (descriptor
, n
);
2792 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
2793 "outside of expected range (%%ld:%%ld)", n
+1, name
);
2795 asprintf (&msg
, "Index '%%ld' of dimension %d "
2796 "outside of expected range (%%ld:%%ld)", n
+1);
2798 fault
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
2800 gfc_trans_runtime_check (true, false, fault
, &se
->pre
, where
, msg
,
2801 fold_convert (long_integer_type_node
, index
),
2802 fold_convert (long_integer_type_node
, tmp_lo
),
2803 fold_convert (long_integer_type_node
, tmp_up
));
2804 fault
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
2806 gfc_trans_runtime_check (true, false, fault
, &se
->pre
, where
, msg
,
2807 fold_convert (long_integer_type_node
, index
),
2808 fold_convert (long_integer_type_node
, tmp_lo
),
2809 fold_convert (long_integer_type_node
, tmp_up
));
2814 tmp_lo
= gfc_conv_array_lbound (descriptor
, n
);
2817 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
2818 "below lower bound of %%ld", n
+1, name
);
2820 asprintf (&msg
, "Index '%%ld' of dimension %d "
2821 "below lower bound of %%ld", n
+1);
2823 fault
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
2825 gfc_trans_runtime_check (true, false, fault
, &se
->pre
, where
, msg
,
2826 fold_convert (long_integer_type_node
, index
),
2827 fold_convert (long_integer_type_node
, tmp_lo
));
2835 /* Return the offset for an index. Performs bound checking for elemental
2836 dimensions. Single element references are processed separately.
2837 DIM is the array dimension, I is the loop dimension. */
2840 conv_array_index_offset (gfc_se
* se
, gfc_ss
* ss
, int dim
, int i
,
2841 gfc_array_ref
* ar
, tree stride
)
2843 gfc_array_info
*info
;
2848 info
= &ss
->info
->data
.array
;
2850 /* Get the index into the array for this dimension. */
2853 gcc_assert (ar
->type
!= AR_ELEMENT
);
2854 switch (ar
->dimen_type
[dim
])
2856 case DIMEN_THIS_IMAGE
:
2860 /* Elemental dimension. */
2861 gcc_assert (info
->subscript
[dim
]
2862 && info
->subscript
[dim
]->info
->type
== GFC_SS_SCALAR
);
2863 /* We've already translated this value outside the loop. */
2864 index
= info
->subscript
[dim
]->info
->data
.scalar
.value
;
2866 index
= trans_array_bound_check (se
, ss
, index
, dim
, &ar
->where
,
2867 ar
->as
->type
!= AS_ASSUMED_SIZE
2868 || dim
< ar
->dimen
- 1);
2872 gcc_assert (info
&& se
->loop
);
2873 gcc_assert (info
->subscript
[dim
]
2874 && info
->subscript
[dim
]->info
->type
== GFC_SS_VECTOR
);
2875 desc
= info
->subscript
[dim
]->info
->data
.array
.descriptor
;
2877 /* Get a zero-based index into the vector. */
2878 index
= fold_build2_loc (input_location
, MINUS_EXPR
,
2879 gfc_array_index_type
,
2880 se
->loop
->loopvar
[i
], se
->loop
->from
[i
]);
2882 /* Multiply the index by the stride. */
2883 index
= fold_build2_loc (input_location
, MULT_EXPR
,
2884 gfc_array_index_type
,
2885 index
, gfc_conv_array_stride (desc
, 0));
2887 /* Read the vector to get an index into info->descriptor. */
2888 data
= build_fold_indirect_ref_loc (input_location
,
2889 gfc_conv_array_data (desc
));
2890 index
= gfc_build_array_ref (data
, index
, NULL
);
2891 index
= gfc_evaluate_now (index
, &se
->pre
);
2892 index
= fold_convert (gfc_array_index_type
, index
);
2894 /* Do any bounds checking on the final info->descriptor index. */
2895 index
= trans_array_bound_check (se
, ss
, index
, dim
, &ar
->where
,
2896 ar
->as
->type
!= AS_ASSUMED_SIZE
2897 || dim
< ar
->dimen
- 1);
2901 /* Scalarized dimension. */
2902 gcc_assert (info
&& se
->loop
);
2904 /* Multiply the loop variable by the stride and delta. */
2905 index
= se
->loop
->loopvar
[i
];
2906 if (!integer_onep (info
->stride
[dim
]))
2907 index
= fold_build2_loc (input_location
, MULT_EXPR
,
2908 gfc_array_index_type
, index
,
2910 if (!integer_zerop (info
->delta
[dim
]))
2911 index
= fold_build2_loc (input_location
, PLUS_EXPR
,
2912 gfc_array_index_type
, index
,
2922 /* Temporary array or derived type component. */
2923 gcc_assert (se
->loop
);
2924 index
= se
->loop
->loopvar
[se
->loop
->order
[i
]];
2926 /* Pointer functions can have stride[0] different from unity.
2927 Use the stride returned by the function call and stored in
2928 the descriptor for the temporary. */
2929 if (se
->ss
&& se
->ss
->info
->type
== GFC_SS_FUNCTION
2930 && se
->ss
->info
->expr
2931 && se
->ss
->info
->expr
->symtree
2932 && se
->ss
->info
->expr
->symtree
->n
.sym
->result
2933 && se
->ss
->info
->expr
->symtree
->n
.sym
->result
->attr
.pointer
)
2934 stride
= gfc_conv_descriptor_stride_get (info
->descriptor
,
2937 if (!integer_zerop (info
->delta
[dim
]))
2938 index
= fold_build2_loc (input_location
, PLUS_EXPR
,
2939 gfc_array_index_type
, index
, info
->delta
[dim
]);
2942 /* Multiply by the stride. */
2943 if (!integer_onep (stride
))
2944 index
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
2951 /* Build a scalarized array reference using the vptr 'size'. */
2954 build_class_array_ref (gfc_se
*se
, tree base
, tree index
)
2961 gfc_expr
*expr
= se
->ss
->info
->expr
;
2966 if (expr
== NULL
|| expr
->ts
.type
!= BT_CLASS
)
2969 if (expr
->symtree
&& expr
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
2970 ts
= &expr
->symtree
->n
.sym
->ts
;
2975 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
2977 if (ref
->type
== REF_COMPONENT
2978 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
2979 && ref
->next
&& ref
->next
->type
== REF_COMPONENT
2980 && strcmp (ref
->next
->u
.c
.component
->name
, "_data") == 0
2982 && ref
->next
->next
->type
== REF_ARRAY
2983 && ref
->next
->next
->u
.ar
.type
!= AR_ELEMENT
)
2985 ts
= &ref
->u
.c
.component
->ts
;
2994 if (class_ref
== NULL
&& expr
->symtree
->n
.sym
->attr
.function
2995 && expr
->symtree
->n
.sym
== expr
->symtree
->n
.sym
->result
)
2997 gcc_assert (expr
->symtree
->n
.sym
->backend_decl
== current_function_decl
);
2998 decl
= gfc_get_fake_result_decl (expr
->symtree
->n
.sym
, 0);
3000 else if (class_ref
== NULL
)
3001 decl
= expr
->symtree
->n
.sym
->backend_decl
;
3004 /* Remove everything after the last class reference, convert the
3005 expression and then recover its tailend once more. */
3007 ref
= class_ref
->next
;
3008 class_ref
->next
= NULL
;
3009 gfc_init_se (&tmpse
, NULL
);
3010 gfc_conv_expr (&tmpse
, expr
);
3012 class_ref
->next
= ref
;
3015 size
= gfc_vtable_size_get (decl
);
3017 /* Build the address of the element. */
3018 type
= TREE_TYPE (TREE_TYPE (base
));
3019 size
= fold_convert (TREE_TYPE (index
), size
);
3020 offset
= fold_build2_loc (input_location
, MULT_EXPR
,
3021 gfc_array_index_type
,
3023 tmp
= gfc_build_addr_expr (pvoid_type_node
, base
);
3024 tmp
= fold_build_pointer_plus_loc (input_location
, tmp
, offset
);
3025 tmp
= fold_convert (build_pointer_type (type
), tmp
);
3027 /* Return the element in the se expression. */
3028 se
->expr
= build_fold_indirect_ref_loc (input_location
, tmp
);
3033 /* Build a scalarized reference to an array. */
3036 gfc_conv_scalarized_array_ref (gfc_se
* se
, gfc_array_ref
* ar
)
3038 gfc_array_info
*info
;
3039 tree decl
= NULL_TREE
;
3047 expr
= ss
->info
->expr
;
3048 info
= &ss
->info
->data
.array
;
3050 n
= se
->loop
->order
[0];
3054 index
= conv_array_index_offset (se
, ss
, ss
->dim
[n
], n
, ar
, info
->stride0
);
3055 /* Add the offset for this dimension to the stored offset for all other
3057 if (!integer_zerop (info
->offset
))
3058 index
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3059 index
, info
->offset
);
3061 if (expr
&& is_subref_array (expr
))
3062 decl
= expr
->symtree
->n
.sym
->backend_decl
;
3064 tmp
= build_fold_indirect_ref_loc (input_location
, info
->data
);
3066 /* Use the vptr 'size' field to access a class the element of a class
3068 if (build_class_array_ref (se
, tmp
, index
))
3071 se
->expr
= gfc_build_array_ref (tmp
, index
, decl
);
3075 /* Translate access of temporary array. */
3078 gfc_conv_tmp_array_ref (gfc_se
* se
)
3080 se
->string_length
= se
->ss
->info
->string_length
;
3081 gfc_conv_scalarized_array_ref (se
, NULL
);
3082 gfc_advance_se_ss_chain (se
);
3085 /* Add T to the offset pair *OFFSET, *CST_OFFSET. */
3088 add_to_offset (tree
*cst_offset
, tree
*offset
, tree t
)
3090 if (TREE_CODE (t
) == INTEGER_CST
)
3091 *cst_offset
= int_const_binop (PLUS_EXPR
, *cst_offset
, t
);
3094 if (!integer_zerop (*offset
))
3095 *offset
= fold_build2_loc (input_location
, PLUS_EXPR
,
3096 gfc_array_index_type
, *offset
, t
);
3104 build_array_ref (tree desc
, tree offset
, tree decl
)
3109 /* Class container types do not always have the GFC_CLASS_TYPE_P
3110 but the canonical type does. */
3111 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc
))
3112 && TREE_CODE (desc
) == COMPONENT_REF
)
3114 type
= TREE_TYPE (TREE_OPERAND (desc
, 0));
3115 if (TYPE_CANONICAL (type
)
3116 && GFC_CLASS_TYPE_P (TYPE_CANONICAL (type
)))
3117 type
= TYPE_CANONICAL (type
);
3122 /* Class array references need special treatment because the assigned
3123 type size needs to be used to point to the element. */
3124 if (type
&& GFC_CLASS_TYPE_P (type
))
3126 type
= gfc_get_element_type (TREE_TYPE (desc
));
3127 tmp
= TREE_OPERAND (desc
, 0);
3128 tmp
= gfc_get_class_array_ref (offset
, tmp
);
3129 tmp
= fold_convert (build_pointer_type (type
), tmp
);
3130 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
3134 tmp
= gfc_conv_array_data (desc
);
3135 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
3136 tmp
= gfc_build_array_ref (tmp
, offset
, decl
);
3141 /* Build an array reference. se->expr already holds the array descriptor.
3142 This should be either a variable, indirect variable reference or component
3143 reference. For arrays which do not have a descriptor, se->expr will be
3145 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
3148 gfc_conv_array_ref (gfc_se
* se
, gfc_array_ref
* ar
, gfc_expr
*expr
,
3152 tree offset
, cst_offset
;
3157 gfc_symbol
* sym
= expr
->symtree
->n
.sym
;
3158 char *var_name
= NULL
;
3162 gcc_assert (ar
->codimen
);
3164 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se
->expr
)))
3165 se
->expr
= build_fold_indirect_ref (gfc_conv_array_data (se
->expr
));
3168 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se
->expr
))
3169 && TREE_CODE (TREE_TYPE (se
->expr
)) == POINTER_TYPE
)
3170 se
->expr
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
3172 /* Use the actual tree type and not the wrapped coarray. */
3173 if (!se
->want_pointer
)
3174 se
->expr
= fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se
->expr
)),
3181 /* Handle scalarized references separately. */
3182 if (ar
->type
!= AR_ELEMENT
)
3184 gfc_conv_scalarized_array_ref (se
, ar
);
3185 gfc_advance_se_ss_chain (se
);
3189 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
3194 len
= strlen (sym
->name
) + 1;
3195 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
3197 if (ref
->type
== REF_ARRAY
&& &ref
->u
.ar
== ar
)
3199 if (ref
->type
== REF_COMPONENT
)
3200 len
+= 1 + strlen (ref
->u
.c
.component
->name
);
3203 var_name
= XALLOCAVEC (char, len
);
3204 strcpy (var_name
, sym
->name
);
3206 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
3208 if (ref
->type
== REF_ARRAY
&& &ref
->u
.ar
== ar
)
3210 if (ref
->type
== REF_COMPONENT
)
3212 strcat (var_name
, "%%");
3213 strcat (var_name
, ref
->u
.c
.component
->name
);
3218 cst_offset
= offset
= gfc_index_zero_node
;
3219 add_to_offset (&cst_offset
, &offset
, gfc_conv_array_offset (se
->expr
));
3221 /* Calculate the offsets from all the dimensions. Make sure to associate
3222 the final offset so that we form a chain of loop invariant summands. */
3223 for (n
= ar
->dimen
- 1; n
>= 0; n
--)
3225 /* Calculate the index for this dimension. */
3226 gfc_init_se (&indexse
, se
);
3227 gfc_conv_expr_type (&indexse
, ar
->start
[n
], gfc_array_index_type
);
3228 gfc_add_block_to_block (&se
->pre
, &indexse
.pre
);
3230 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
3232 /* Check array bounds. */
3236 /* Evaluate the indexse.expr only once. */
3237 indexse
.expr
= save_expr (indexse
.expr
);
3240 tmp
= gfc_conv_array_lbound (se
->expr
, n
);
3241 if (sym
->attr
.temporary
)
3243 gfc_init_se (&tmpse
, se
);
3244 gfc_conv_expr_type (&tmpse
, ar
->as
->lower
[n
],
3245 gfc_array_index_type
);
3246 gfc_add_block_to_block (&se
->pre
, &tmpse
.pre
);
3250 cond
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
3252 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
3253 "below lower bound of %%ld", n
+1, var_name
);
3254 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, where
, msg
,
3255 fold_convert (long_integer_type_node
,
3257 fold_convert (long_integer_type_node
, tmp
));
3260 /* Upper bound, but not for the last dimension of assumed-size
3262 if (n
< ar
->dimen
- 1 || ar
->as
->type
!= AS_ASSUMED_SIZE
)
3264 tmp
= gfc_conv_array_ubound (se
->expr
, n
);
3265 if (sym
->attr
.temporary
)
3267 gfc_init_se (&tmpse
, se
);
3268 gfc_conv_expr_type (&tmpse
, ar
->as
->upper
[n
],
3269 gfc_array_index_type
);
3270 gfc_add_block_to_block (&se
->pre
, &tmpse
.pre
);
3274 cond
= fold_build2_loc (input_location
, GT_EXPR
,
3275 boolean_type_node
, indexse
.expr
, tmp
);
3276 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
3277 "above upper bound of %%ld", n
+1, var_name
);
3278 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, where
, msg
,
3279 fold_convert (long_integer_type_node
,
3281 fold_convert (long_integer_type_node
, tmp
));
3286 /* Multiply the index by the stride. */
3287 stride
= gfc_conv_array_stride (se
->expr
, n
);
3288 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
3289 indexse
.expr
, stride
);
3291 /* And add it to the total. */
3292 add_to_offset (&cst_offset
, &offset
, tmp
);
3295 if (!integer_zerop (cst_offset
))
3296 offset
= fold_build2_loc (input_location
, PLUS_EXPR
,
3297 gfc_array_index_type
, offset
, cst_offset
);
3299 se
->expr
= build_array_ref (se
->expr
, offset
, sym
->backend_decl
);
3303 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
3304 LOOP_DIM dimension (if any) to array's offset. */
3307 add_array_offset (stmtblock_t
*pblock
, gfc_loopinfo
*loop
, gfc_ss
*ss
,
3308 gfc_array_ref
*ar
, int array_dim
, int loop_dim
)
3311 gfc_array_info
*info
;
3314 info
= &ss
->info
->data
.array
;
3316 gfc_init_se (&se
, NULL
);
3318 se
.expr
= info
->descriptor
;
3319 stride
= gfc_conv_array_stride (info
->descriptor
, array_dim
);
3320 index
= conv_array_index_offset (&se
, ss
, array_dim
, loop_dim
, ar
, stride
);
3321 gfc_add_block_to_block (pblock
, &se
.pre
);
3323 info
->offset
= fold_build2_loc (input_location
, PLUS_EXPR
,
3324 gfc_array_index_type
,
3325 info
->offset
, index
);
3326 info
->offset
= gfc_evaluate_now (info
->offset
, pblock
);
3330 /* Generate the code to be executed immediately before entering a
3331 scalarization loop. */
3334 gfc_trans_preloop_setup (gfc_loopinfo
* loop
, int dim
, int flag
,
3335 stmtblock_t
* pblock
)
3338 gfc_ss_info
*ss_info
;
3339 gfc_array_info
*info
;
3340 gfc_ss_type ss_type
;
3342 gfc_loopinfo
*ploop
;
3346 /* This code will be executed before entering the scalarization loop
3347 for this dimension. */
3348 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3352 if ((ss_info
->useflags
& flag
) == 0)
3355 ss_type
= ss_info
->type
;
3356 if (ss_type
!= GFC_SS_SECTION
3357 && ss_type
!= GFC_SS_FUNCTION
3358 && ss_type
!= GFC_SS_CONSTRUCTOR
3359 && ss_type
!= GFC_SS_COMPONENT
)
3362 info
= &ss_info
->data
.array
;
3364 gcc_assert (dim
< ss
->dimen
);
3365 gcc_assert (ss
->dimen
== loop
->dimen
);
3368 ar
= &info
->ref
->u
.ar
;
3372 if (dim
== loop
->dimen
- 1 && loop
->parent
!= NULL
)
3374 /* If we are in the outermost dimension of this loop, the previous
3375 dimension shall be in the parent loop. */
3376 gcc_assert (ss
->parent
!= NULL
);
3379 ploop
= loop
->parent
;
3381 /* ss and ss->parent are about the same array. */
3382 gcc_assert (ss_info
== pss
->info
);
3390 if (dim
== loop
->dimen
- 1)
3395 /* For the time being, there is no loop reordering. */
3396 gcc_assert (i
== ploop
->order
[i
]);
3397 i
= ploop
->order
[i
];
3399 if (dim
== loop
->dimen
- 1 && loop
->parent
== NULL
)
3401 stride
= gfc_conv_array_stride (info
->descriptor
,
3402 innermost_ss (ss
)->dim
[i
]);
3404 /* Calculate the stride of the innermost loop. Hopefully this will
3405 allow the backend optimizers to do their stuff more effectively.
3407 info
->stride0
= gfc_evaluate_now (stride
, pblock
);
3409 /* For the outermost loop calculate the offset due to any
3410 elemental dimensions. It will have been initialized with the
3411 base offset of the array. */
3414 for (i
= 0; i
< ar
->dimen
; i
++)
3416 if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
)
3419 add_array_offset (pblock
, loop
, ss
, ar
, i
, /* unused */ -1);
3424 /* Add the offset for the previous loop dimension. */
3425 add_array_offset (pblock
, ploop
, ss
, ar
, pss
->dim
[i
], i
);
3427 /* Remember this offset for the second loop. */
3428 if (dim
== loop
->temp_dim
- 1 && loop
->parent
== NULL
)
3429 info
->saved_offset
= info
->offset
;
3434 /* Start a scalarized expression. Creates a scope and declares loop
3438 gfc_start_scalarized_body (gfc_loopinfo
* loop
, stmtblock_t
* pbody
)
3444 gcc_assert (!loop
->array_parameter
);
3446 for (dim
= loop
->dimen
- 1; dim
>= 0; dim
--)
3448 n
= loop
->order
[dim
];
3450 gfc_start_block (&loop
->code
[n
]);
3452 /* Create the loop variable. */
3453 loop
->loopvar
[n
] = gfc_create_var (gfc_array_index_type
, "S");
3455 if (dim
< loop
->temp_dim
)
3459 /* Calculate values that will be constant within this loop. */
3460 gfc_trans_preloop_setup (loop
, dim
, flags
, &loop
->code
[n
]);
3462 gfc_start_block (pbody
);
3466 /* Generates the actual loop code for a scalarization loop. */
3469 gfc_trans_scalarized_loop_end (gfc_loopinfo
* loop
, int n
,
3470 stmtblock_t
* pbody
)
3481 if ((ompws_flags
& (OMPWS_WORKSHARE_FLAG
| OMPWS_SCALARIZER_WS
))
3482 == (OMPWS_WORKSHARE_FLAG
| OMPWS_SCALARIZER_WS
)
3483 && n
== loop
->dimen
- 1)
3485 /* We create an OMP_FOR construct for the outermost scalarized loop. */
3486 init
= make_tree_vec (1);
3487 cond
= make_tree_vec (1);
3488 incr
= make_tree_vec (1);
3490 /* Cycle statement is implemented with a goto. Exit statement must not
3491 be present for this loop. */
3492 exit_label
= gfc_build_label_decl (NULL_TREE
);
3493 TREE_USED (exit_label
) = 1;
3495 /* Label for cycle statements (if needed). */
3496 tmp
= build1_v (LABEL_EXPR
, exit_label
);
3497 gfc_add_expr_to_block (pbody
, tmp
);
3499 stmt
= make_node (OMP_FOR
);
3501 TREE_TYPE (stmt
) = void_type_node
;
3502 OMP_FOR_BODY (stmt
) = loopbody
= gfc_finish_block (pbody
);
3504 OMP_FOR_CLAUSES (stmt
) = build_omp_clause (input_location
,
3505 OMP_CLAUSE_SCHEDULE
);
3506 OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt
))
3507 = OMP_CLAUSE_SCHEDULE_STATIC
;
3508 if (ompws_flags
& OMPWS_NOWAIT
)
3509 OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt
))
3510 = build_omp_clause (input_location
, OMP_CLAUSE_NOWAIT
);
3512 /* Initialize the loopvar. */
3513 TREE_VEC_ELT (init
, 0) = build2_v (MODIFY_EXPR
, loop
->loopvar
[n
],
3515 OMP_FOR_INIT (stmt
) = init
;
3516 /* The exit condition. */
3517 TREE_VEC_ELT (cond
, 0) = build2_loc (input_location
, LE_EXPR
,
3519 loop
->loopvar
[n
], loop
->to
[n
]);
3520 SET_EXPR_LOCATION (TREE_VEC_ELT (cond
, 0), input_location
);
3521 OMP_FOR_COND (stmt
) = cond
;
3522 /* Increment the loopvar. */
3523 tmp
= build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3524 loop
->loopvar
[n
], gfc_index_one_node
);
3525 TREE_VEC_ELT (incr
, 0) = fold_build2_loc (input_location
, MODIFY_EXPR
,
3526 void_type_node
, loop
->loopvar
[n
], tmp
);
3527 OMP_FOR_INCR (stmt
) = incr
;
3529 ompws_flags
&= ~OMPWS_CURR_SINGLEUNIT
;
3530 gfc_add_expr_to_block (&loop
->code
[n
], stmt
);
3534 bool reverse_loop
= (loop
->reverse
[n
] == GFC_REVERSE_SET
)
3535 && (loop
->temp_ss
== NULL
);
3537 loopbody
= gfc_finish_block (pbody
);
3541 tmp
= loop
->from
[n
];
3542 loop
->from
[n
] = loop
->to
[n
];
3546 /* Initialize the loopvar. */
3547 if (loop
->loopvar
[n
] != loop
->from
[n
])
3548 gfc_add_modify (&loop
->code
[n
], loop
->loopvar
[n
], loop
->from
[n
]);
3550 exit_label
= gfc_build_label_decl (NULL_TREE
);
3552 /* Generate the loop body. */
3553 gfc_init_block (&block
);
3555 /* The exit condition. */
3556 cond
= fold_build2_loc (input_location
, reverse_loop
? LT_EXPR
: GT_EXPR
,
3557 boolean_type_node
, loop
->loopvar
[n
], loop
->to
[n
]);
3558 tmp
= build1_v (GOTO_EXPR
, exit_label
);
3559 TREE_USED (exit_label
) = 1;
3560 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
3561 gfc_add_expr_to_block (&block
, tmp
);
3563 /* The main body. */
3564 gfc_add_expr_to_block (&block
, loopbody
);
3566 /* Increment the loopvar. */
3567 tmp
= fold_build2_loc (input_location
,
3568 reverse_loop
? MINUS_EXPR
: PLUS_EXPR
,
3569 gfc_array_index_type
, loop
->loopvar
[n
],
3570 gfc_index_one_node
);
3572 gfc_add_modify (&block
, loop
->loopvar
[n
], tmp
);
3574 /* Build the loop. */
3575 tmp
= gfc_finish_block (&block
);
3576 tmp
= build1_v (LOOP_EXPR
, tmp
);
3577 gfc_add_expr_to_block (&loop
->code
[n
], tmp
);
3579 /* Add the exit label. */
3580 tmp
= build1_v (LABEL_EXPR
, exit_label
);
3581 gfc_add_expr_to_block (&loop
->code
[n
], tmp
);
3587 /* Finishes and generates the loops for a scalarized expression. */
3590 gfc_trans_scalarizing_loops (gfc_loopinfo
* loop
, stmtblock_t
* body
)
3595 stmtblock_t
*pblock
;
3599 /* Generate the loops. */
3600 for (dim
= 0; dim
< loop
->dimen
; dim
++)
3602 n
= loop
->order
[dim
];
3603 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
3604 loop
->loopvar
[n
] = NULL_TREE
;
3605 pblock
= &loop
->code
[n
];
3608 tmp
= gfc_finish_block (pblock
);
3609 gfc_add_expr_to_block (&loop
->pre
, tmp
);
3611 /* Clear all the used flags. */
3612 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3613 if (ss
->parent
== NULL
)
3614 ss
->info
->useflags
= 0;
3618 /* Finish the main body of a scalarized expression, and start the secondary
3622 gfc_trans_scalarized_loop_boundary (gfc_loopinfo
* loop
, stmtblock_t
* body
)
3626 stmtblock_t
*pblock
;
3630 /* We finish as many loops as are used by the temporary. */
3631 for (dim
= 0; dim
< loop
->temp_dim
- 1; dim
++)
3633 n
= loop
->order
[dim
];
3634 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
3635 loop
->loopvar
[n
] = NULL_TREE
;
3636 pblock
= &loop
->code
[n
];
3639 /* We don't want to finish the outermost loop entirely. */
3640 n
= loop
->order
[loop
->temp_dim
- 1];
3641 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
3643 /* Restore the initial offsets. */
3644 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3646 gfc_ss_type ss_type
;
3647 gfc_ss_info
*ss_info
;
3651 if ((ss_info
->useflags
& 2) == 0)
3654 ss_type
= ss_info
->type
;
3655 if (ss_type
!= GFC_SS_SECTION
3656 && ss_type
!= GFC_SS_FUNCTION
3657 && ss_type
!= GFC_SS_CONSTRUCTOR
3658 && ss_type
!= GFC_SS_COMPONENT
)
3661 ss_info
->data
.array
.offset
= ss_info
->data
.array
.saved_offset
;
3664 /* Restart all the inner loops we just finished. */
3665 for (dim
= loop
->temp_dim
- 2; dim
>= 0; dim
--)
3667 n
= loop
->order
[dim
];
3669 gfc_start_block (&loop
->code
[n
]);
3671 loop
->loopvar
[n
] = gfc_create_var (gfc_array_index_type
, "Q");
3673 gfc_trans_preloop_setup (loop
, dim
, 2, &loop
->code
[n
]);
3676 /* Start a block for the secondary copying code. */
3677 gfc_start_block (body
);
3681 /* Precalculate (either lower or upper) bound of an array section.
3682 BLOCK: Block in which the (pre)calculation code will go.
3683 BOUNDS[DIM]: Where the bound value will be stored once evaluated.
3684 VALUES[DIM]: Specified bound (NULL <=> unspecified).
3685 DESC: Array descriptor from which the bound will be picked if unspecified
3686 (either lower or upper bound according to LBOUND). */
3689 evaluate_bound (stmtblock_t
*block
, tree
*bounds
, gfc_expr
** values
,
3690 tree desc
, int dim
, bool lbound
)
3693 gfc_expr
* input_val
= values
[dim
];
3694 tree
*output
= &bounds
[dim
];
3699 /* Specified section bound. */
3700 gfc_init_se (&se
, NULL
);
3701 gfc_conv_expr_type (&se
, input_val
, gfc_array_index_type
);
3702 gfc_add_block_to_block (block
, &se
.pre
);
3707 /* No specific bound specified so use the bound of the array. */
3708 *output
= lbound
? gfc_conv_array_lbound (desc
, dim
) :
3709 gfc_conv_array_ubound (desc
, dim
);
3711 *output
= gfc_evaluate_now (*output
, block
);
3715 /* Calculate the lower bound of an array section. */
3718 gfc_conv_section_startstride (gfc_loopinfo
* loop
, gfc_ss
* ss
, int dim
)
3720 gfc_expr
*stride
= NULL
;
3723 gfc_array_info
*info
;
3726 gcc_assert (ss
->info
->type
== GFC_SS_SECTION
);
3728 info
= &ss
->info
->data
.array
;
3729 ar
= &info
->ref
->u
.ar
;
3731 if (ar
->dimen_type
[dim
] == DIMEN_VECTOR
)
3733 /* We use a zero-based index to access the vector. */
3734 info
->start
[dim
] = gfc_index_zero_node
;
3735 info
->end
[dim
] = NULL
;
3736 info
->stride
[dim
] = gfc_index_one_node
;
3740 gcc_assert (ar
->dimen_type
[dim
] == DIMEN_RANGE
3741 || ar
->dimen_type
[dim
] == DIMEN_THIS_IMAGE
);
3742 desc
= info
->descriptor
;
3743 stride
= ar
->stride
[dim
];
3745 /* Calculate the start of the range. For vector subscripts this will
3746 be the range of the vector. */
3747 evaluate_bound (&loop
->pre
, info
->start
, ar
->start
, desc
, dim
, true);
3749 /* Similarly calculate the end. Although this is not used in the
3750 scalarizer, it is needed when checking bounds and where the end
3751 is an expression with side-effects. */
3752 evaluate_bound (&loop
->pre
, info
->end
, ar
->end
, desc
, dim
, false);
3754 /* Calculate the stride. */
3756 info
->stride
[dim
] = gfc_index_one_node
;
3759 gfc_init_se (&se
, NULL
);
3760 gfc_conv_expr_type (&se
, stride
, gfc_array_index_type
);
3761 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
3762 info
->stride
[dim
] = gfc_evaluate_now (se
.expr
, &loop
->pre
);
3767 /* Calculates the range start and stride for a SS chain. Also gets the
3768 descriptor and data pointer. The range of vector subscripts is the size
3769 of the vector. Array bounds are also checked. */
3772 gfc_conv_ss_startstride (gfc_loopinfo
* loop
)
3780 /* Determine the rank of the loop. */
3781 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3783 switch (ss
->info
->type
)
3785 case GFC_SS_SECTION
:
3786 case GFC_SS_CONSTRUCTOR
:
3787 case GFC_SS_FUNCTION
:
3788 case GFC_SS_COMPONENT
:
3789 loop
->dimen
= ss
->dimen
;
3792 /* As usual, lbound and ubound are exceptions!. */
3793 case GFC_SS_INTRINSIC
:
3794 switch (ss
->info
->expr
->value
.function
.isym
->id
)
3796 case GFC_ISYM_LBOUND
:
3797 case GFC_ISYM_UBOUND
:
3798 case GFC_ISYM_LCOBOUND
:
3799 case GFC_ISYM_UCOBOUND
:
3800 case GFC_ISYM_THIS_IMAGE
:
3801 loop
->dimen
= ss
->dimen
;
3813 /* We should have determined the rank of the expression by now. If
3814 not, that's bad news. */
3818 /* Loop over all the SS in the chain. */
3819 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3821 gfc_ss_info
*ss_info
;
3822 gfc_array_info
*info
;
3826 expr
= ss_info
->expr
;
3827 info
= &ss_info
->data
.array
;
3829 if (expr
&& expr
->shape
&& !info
->shape
)
3830 info
->shape
= expr
->shape
;
3832 switch (ss_info
->type
)
3834 case GFC_SS_SECTION
:
3835 /* Get the descriptor for the array. If it is a cross loops array,
3836 we got the descriptor already in the outermost loop. */
3837 if (ss
->parent
== NULL
)
3838 gfc_conv_ss_descriptor (&loop
->pre
, ss
, !loop
->array_parameter
);
3840 for (n
= 0; n
< ss
->dimen
; n
++)
3841 gfc_conv_section_startstride (loop
, ss
, ss
->dim
[n
]);
3844 case GFC_SS_INTRINSIC
:
3845 switch (expr
->value
.function
.isym
->id
)
3847 /* Fall through to supply start and stride. */
3848 case GFC_ISYM_LBOUND
:
3849 case GFC_ISYM_UBOUND
:
3853 /* This is the variant without DIM=... */
3854 gcc_assert (expr
->value
.function
.actual
->next
->expr
== NULL
);
3856 arg
= expr
->value
.function
.actual
->expr
;
3857 if (arg
->rank
== -1)
3862 /* The rank (hence the return value's shape) is unknown,
3863 we have to retrieve it. */
3864 gfc_init_se (&se
, NULL
);
3865 se
.descriptor_only
= 1;
3866 gfc_conv_expr (&se
, arg
);
3867 /* This is a bare variable, so there is no preliminary
3869 gcc_assert (se
.pre
.head
== NULL_TREE
3870 && se
.post
.head
== NULL_TREE
);
3871 rank
= gfc_conv_descriptor_rank (se
.expr
);
3872 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
3873 gfc_array_index_type
,
3874 fold_convert (gfc_array_index_type
,
3876 gfc_index_one_node
);
3877 info
->end
[0] = gfc_evaluate_now (tmp
, &loop
->pre
);
3878 info
->start
[0] = gfc_index_zero_node
;
3879 info
->stride
[0] = gfc_index_one_node
;
3882 /* Otherwise fall through GFC_SS_FUNCTION. */
3884 case GFC_ISYM_LCOBOUND
:
3885 case GFC_ISYM_UCOBOUND
:
3886 case GFC_ISYM_THIS_IMAGE
:
3893 case GFC_SS_CONSTRUCTOR
:
3894 case GFC_SS_FUNCTION
:
3895 for (n
= 0; n
< ss
->dimen
; n
++)
3897 int dim
= ss
->dim
[n
];
3899 info
->start
[dim
] = gfc_index_zero_node
;
3900 info
->end
[dim
] = gfc_index_zero_node
;
3901 info
->stride
[dim
] = gfc_index_one_node
;
3910 /* The rest is just runtime bound checking. */
3911 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
3914 tree lbound
, ubound
;
3916 tree size
[GFC_MAX_DIMENSIONS
];
3917 tree stride_pos
, stride_neg
, non_zerosized
, tmp2
, tmp3
;
3918 gfc_array_info
*info
;
3922 gfc_start_block (&block
);
3924 for (n
= 0; n
< loop
->dimen
; n
++)
3925 size
[n
] = NULL_TREE
;
3927 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
3930 gfc_ss_info
*ss_info
;
3933 const char *expr_name
;
3936 if (ss_info
->type
!= GFC_SS_SECTION
)
3939 /* Catch allocatable lhs in f2003. */
3940 if (gfc_option
.flag_realloc_lhs
&& ss
->is_alloc_lhs
)
3943 expr
= ss_info
->expr
;
3944 expr_loc
= &expr
->where
;
3945 expr_name
= expr
->symtree
->name
;
3947 gfc_start_block (&inner
);
3949 /* TODO: range checking for mapped dimensions. */
3950 info
= &ss_info
->data
.array
;
3952 /* This code only checks ranges. Elemental and vector
3953 dimensions are checked later. */
3954 for (n
= 0; n
< loop
->dimen
; n
++)
3959 if (info
->ref
->u
.ar
.dimen_type
[dim
] != DIMEN_RANGE
)
3962 if (dim
== info
->ref
->u
.ar
.dimen
- 1
3963 && info
->ref
->u
.ar
.as
->type
== AS_ASSUMED_SIZE
)
3964 check_upper
= false;
3968 /* Zero stride is not allowed. */
3969 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
3970 info
->stride
[dim
], gfc_index_zero_node
);
3971 asprintf (&msg
, "Zero stride is not allowed, for dimension %d "
3972 "of array '%s'", dim
+ 1, expr_name
);
3973 gfc_trans_runtime_check (true, false, tmp
, &inner
,
3977 desc
= info
->descriptor
;
3979 /* This is the run-time equivalent of resolve.c's
3980 check_dimension(). The logical is more readable there
3981 than it is here, with all the trees. */
3982 lbound
= gfc_conv_array_lbound (desc
, dim
);
3983 end
= info
->end
[dim
];
3985 ubound
= gfc_conv_array_ubound (desc
, dim
);
3989 /* non_zerosized is true when the selected range is not
3991 stride_pos
= fold_build2_loc (input_location
, GT_EXPR
,
3992 boolean_type_node
, info
->stride
[dim
],
3993 gfc_index_zero_node
);
3994 tmp
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
3995 info
->start
[dim
], end
);
3996 stride_pos
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
3997 boolean_type_node
, stride_pos
, tmp
);
3999 stride_neg
= fold_build2_loc (input_location
, LT_EXPR
,
4001 info
->stride
[dim
], gfc_index_zero_node
);
4002 tmp
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
4003 info
->start
[dim
], end
);
4004 stride_neg
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4007 non_zerosized
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
4009 stride_pos
, stride_neg
);
4011 /* Check the start of the range against the lower and upper
4012 bounds of the array, if the range is not empty.
4013 If upper bound is present, include both bounds in the
4017 tmp
= fold_build2_loc (input_location
, LT_EXPR
,
4019 info
->start
[dim
], lbound
);
4020 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4022 non_zerosized
, tmp
);
4023 tmp2
= fold_build2_loc (input_location
, GT_EXPR
,
4025 info
->start
[dim
], ubound
);
4026 tmp2
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4028 non_zerosized
, tmp2
);
4029 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
4030 "outside of expected range (%%ld:%%ld)",
4031 dim
+ 1, expr_name
);
4032 gfc_trans_runtime_check (true, false, tmp
, &inner
,
4034 fold_convert (long_integer_type_node
, info
->start
[dim
]),
4035 fold_convert (long_integer_type_node
, lbound
),
4036 fold_convert (long_integer_type_node
, ubound
));
4037 gfc_trans_runtime_check (true, false, tmp2
, &inner
,
4039 fold_convert (long_integer_type_node
, info
->start
[dim
]),
4040 fold_convert (long_integer_type_node
, lbound
),
4041 fold_convert (long_integer_type_node
, ubound
));
4046 tmp
= fold_build2_loc (input_location
, LT_EXPR
,
4048 info
->start
[dim
], lbound
);
4049 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4050 boolean_type_node
, non_zerosized
, tmp
);
4051 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
4052 "below lower bound of %%ld",
4053 dim
+ 1, expr_name
);
4054 gfc_trans_runtime_check (true, false, tmp
, &inner
,
4056 fold_convert (long_integer_type_node
, info
->start
[dim
]),
4057 fold_convert (long_integer_type_node
, lbound
));
4061 /* Compute the last element of the range, which is not
4062 necessarily "end" (think 0:5:3, which doesn't contain 5)
4063 and check it against both lower and upper bounds. */
4065 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4066 gfc_array_index_type
, end
,
4068 tmp
= fold_build2_loc (input_location
, TRUNC_MOD_EXPR
,
4069 gfc_array_index_type
, tmp
,
4071 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4072 gfc_array_index_type
, end
, tmp
);
4073 tmp2
= fold_build2_loc (input_location
, LT_EXPR
,
4074 boolean_type_node
, tmp
, lbound
);
4075 tmp2
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4076 boolean_type_node
, non_zerosized
, tmp2
);
4079 tmp3
= fold_build2_loc (input_location
, GT_EXPR
,
4080 boolean_type_node
, tmp
, ubound
);
4081 tmp3
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
4082 boolean_type_node
, non_zerosized
, tmp3
);
4083 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
4084 "outside of expected range (%%ld:%%ld)",
4085 dim
+ 1, expr_name
);
4086 gfc_trans_runtime_check (true, false, tmp2
, &inner
,
4088 fold_convert (long_integer_type_node
, tmp
),
4089 fold_convert (long_integer_type_node
, ubound
),
4090 fold_convert (long_integer_type_node
, lbound
));
4091 gfc_trans_runtime_check (true, false, tmp3
, &inner
,
4093 fold_convert (long_integer_type_node
, tmp
),
4094 fold_convert (long_integer_type_node
, ubound
),
4095 fold_convert (long_integer_type_node
, lbound
));
4100 asprintf (&msg
, "Index '%%ld' of dimension %d of array '%s' "
4101 "below lower bound of %%ld",
4102 dim
+ 1, expr_name
);
4103 gfc_trans_runtime_check (true, false, tmp2
, &inner
,
4105 fold_convert (long_integer_type_node
, tmp
),
4106 fold_convert (long_integer_type_node
, lbound
));
4110 /* Check the section sizes match. */
4111 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4112 gfc_array_index_type
, end
,
4114 tmp
= fold_build2_loc (input_location
, FLOOR_DIV_EXPR
,
4115 gfc_array_index_type
, tmp
,
4117 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4118 gfc_array_index_type
,
4119 gfc_index_one_node
, tmp
);
4120 tmp
= fold_build2_loc (input_location
, MAX_EXPR
,
4121 gfc_array_index_type
, tmp
,
4122 build_int_cst (gfc_array_index_type
, 0));
4123 /* We remember the size of the first section, and check all the
4124 others against this. */
4127 tmp3
= fold_build2_loc (input_location
, NE_EXPR
,
4128 boolean_type_node
, tmp
, size
[n
]);
4129 asprintf (&msg
, "Array bound mismatch for dimension %d "
4130 "of array '%s' (%%ld/%%ld)",
4131 dim
+ 1, expr_name
);
4133 gfc_trans_runtime_check (true, false, tmp3
, &inner
,
4135 fold_convert (long_integer_type_node
, tmp
),
4136 fold_convert (long_integer_type_node
, size
[n
]));
4141 size
[n
] = gfc_evaluate_now (tmp
, &inner
);
4144 tmp
= gfc_finish_block (&inner
);
4146 /* For optional arguments, only check bounds if the argument is
4148 if (expr
->symtree
->n
.sym
->attr
.optional
4149 || expr
->symtree
->n
.sym
->attr
.not_always_present
)
4150 tmp
= build3_v (COND_EXPR
,
4151 gfc_conv_expr_present (expr
->symtree
->n
.sym
),
4152 tmp
, build_empty_stmt (input_location
));
4154 gfc_add_expr_to_block (&block
, tmp
);
4158 tmp
= gfc_finish_block (&block
);
4159 gfc_add_expr_to_block (&loop
->pre
, tmp
);
4162 for (loop
= loop
->nested
; loop
; loop
= loop
->next
)
4163 gfc_conv_ss_startstride (loop
);
4166 /* Return true if both symbols could refer to the same data object. Does
4167 not take account of aliasing due to equivalence statements. */
4170 symbols_could_alias (gfc_symbol
*lsym
, gfc_symbol
*rsym
, bool lsym_pointer
,
4171 bool lsym_target
, bool rsym_pointer
, bool rsym_target
)
4173 /* Aliasing isn't possible if the symbols have different base types. */
4174 if (gfc_compare_types (&lsym
->ts
, &rsym
->ts
) == 0)
4177 /* Pointers can point to other pointers and target objects. */
4179 if ((lsym_pointer
&& (rsym_pointer
|| rsym_target
))
4180 || (rsym_pointer
&& (lsym_pointer
|| lsym_target
)))
4183 /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
4184 and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
4186 if (lsym_target
&& rsym_target
4187 && ((lsym
->attr
.dummy
&& !lsym
->attr
.contiguous
4188 && (!lsym
->attr
.dimension
|| lsym
->as
->type
== AS_ASSUMED_SHAPE
))
4189 || (rsym
->attr
.dummy
&& !rsym
->attr
.contiguous
4190 && (!rsym
->attr
.dimension
4191 || rsym
->as
->type
== AS_ASSUMED_SHAPE
))))
4198 /* Return true if the two SS could be aliased, i.e. both point to the same data
4200 /* TODO: resolve aliases based on frontend expressions. */
4203 gfc_could_be_alias (gfc_ss
* lss
, gfc_ss
* rss
)
4207 gfc_expr
*lexpr
, *rexpr
;
4210 bool lsym_pointer
, lsym_target
, rsym_pointer
, rsym_target
;
4212 lexpr
= lss
->info
->expr
;
4213 rexpr
= rss
->info
->expr
;
4215 lsym
= lexpr
->symtree
->n
.sym
;
4216 rsym
= rexpr
->symtree
->n
.sym
;
4218 lsym_pointer
= lsym
->attr
.pointer
;
4219 lsym_target
= lsym
->attr
.target
;
4220 rsym_pointer
= rsym
->attr
.pointer
;
4221 rsym_target
= rsym
->attr
.target
;
4223 if (symbols_could_alias (lsym
, rsym
, lsym_pointer
, lsym_target
,
4224 rsym_pointer
, rsym_target
))
4227 if (rsym
->ts
.type
!= BT_DERIVED
&& rsym
->ts
.type
!= BT_CLASS
4228 && lsym
->ts
.type
!= BT_DERIVED
&& lsym
->ts
.type
!= BT_CLASS
)
4231 /* For derived types we must check all the component types. We can ignore
4232 array references as these will have the same base type as the previous
4234 for (lref
= lexpr
->ref
; lref
!= lss
->info
->data
.array
.ref
; lref
= lref
->next
)
4236 if (lref
->type
!= REF_COMPONENT
)
4239 lsym_pointer
= lsym_pointer
|| lref
->u
.c
.sym
->attr
.pointer
;
4240 lsym_target
= lsym_target
|| lref
->u
.c
.sym
->attr
.target
;
4242 if (symbols_could_alias (lref
->u
.c
.sym
, rsym
, lsym_pointer
, lsym_target
,
4243 rsym_pointer
, rsym_target
))
4246 if ((lsym_pointer
&& (rsym_pointer
|| rsym_target
))
4247 || (rsym_pointer
&& (lsym_pointer
|| lsym_target
)))
4249 if (gfc_compare_types (&lref
->u
.c
.component
->ts
,
4254 for (rref
= rexpr
->ref
; rref
!= rss
->info
->data
.array
.ref
;
4257 if (rref
->type
!= REF_COMPONENT
)
4260 rsym_pointer
= rsym_pointer
|| rref
->u
.c
.sym
->attr
.pointer
;
4261 rsym_target
= lsym_target
|| rref
->u
.c
.sym
->attr
.target
;
4263 if (symbols_could_alias (lref
->u
.c
.sym
, rref
->u
.c
.sym
,
4264 lsym_pointer
, lsym_target
,
4265 rsym_pointer
, rsym_target
))
4268 if ((lsym_pointer
&& (rsym_pointer
|| rsym_target
))
4269 || (rsym_pointer
&& (lsym_pointer
|| lsym_target
)))
4271 if (gfc_compare_types (&lref
->u
.c
.component
->ts
,
4272 &rref
->u
.c
.sym
->ts
))
4274 if (gfc_compare_types (&lref
->u
.c
.sym
->ts
,
4275 &rref
->u
.c
.component
->ts
))
4277 if (gfc_compare_types (&lref
->u
.c
.component
->ts
,
4278 &rref
->u
.c
.component
->ts
))
4284 lsym_pointer
= lsym
->attr
.pointer
;
4285 lsym_target
= lsym
->attr
.target
;
4286 lsym_pointer
= lsym
->attr
.pointer
;
4287 lsym_target
= lsym
->attr
.target
;
4289 for (rref
= rexpr
->ref
; rref
!= rss
->info
->data
.array
.ref
; rref
= rref
->next
)
4291 if (rref
->type
!= REF_COMPONENT
)
4294 rsym_pointer
= rsym_pointer
|| rref
->u
.c
.sym
->attr
.pointer
;
4295 rsym_target
= lsym_target
|| rref
->u
.c
.sym
->attr
.target
;
4297 if (symbols_could_alias (rref
->u
.c
.sym
, lsym
,
4298 lsym_pointer
, lsym_target
,
4299 rsym_pointer
, rsym_target
))
4302 if ((lsym_pointer
&& (rsym_pointer
|| rsym_target
))
4303 || (rsym_pointer
&& (lsym_pointer
|| lsym_target
)))
4305 if (gfc_compare_types (&lsym
->ts
, &rref
->u
.c
.component
->ts
))
4314 /* Resolve array data dependencies. Creates a temporary if required. */
4315 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
4319 gfc_conv_resolve_dependencies (gfc_loopinfo
* loop
, gfc_ss
* dest
,
4325 gfc_expr
*dest_expr
;
4330 loop
->temp_ss
= NULL
;
4331 dest_expr
= dest
->info
->expr
;
4333 for (ss
= rss
; ss
!= gfc_ss_terminator
; ss
= ss
->next
)
4335 if (ss
->info
->type
!= GFC_SS_SECTION
)
4338 ss_expr
= ss
->info
->expr
;
4340 if (dest_expr
->symtree
->n
.sym
!= ss_expr
->symtree
->n
.sym
)
4342 if (gfc_could_be_alias (dest
, ss
)
4343 || gfc_are_equivalenced_arrays (dest_expr
, ss_expr
))
4351 lref
= dest_expr
->ref
;
4352 rref
= ss_expr
->ref
;
4354 nDepend
= gfc_dep_resolver (lref
, rref
, &loop
->reverse
[0]);
4359 for (i
= 0; i
< dest
->dimen
; i
++)
4360 for (j
= 0; j
< ss
->dimen
; j
++)
4362 && dest
->dim
[i
] == ss
->dim
[j
])
4364 /* If we don't access array elements in the same order,
4365 there is a dependency. */
4370 /* TODO : loop shifting. */
4373 /* Mark the dimensions for LOOP SHIFTING */
4374 for (n
= 0; n
< loop
->dimen
; n
++)
4376 int dim
= dest
->data
.info
.dim
[n
];
4378 if (lref
->u
.ar
.dimen_type
[dim
] == DIMEN_VECTOR
)
4380 else if (! gfc_is_same_range (&lref
->u
.ar
,
4381 &rref
->u
.ar
, dim
, 0))
4385 /* Put all the dimensions with dependencies in the
4388 for (n
= 0; n
< loop
->dimen
; n
++)
4390 gcc_assert (loop
->order
[n
] == n
);
4392 loop
->order
[dim
++] = n
;
4394 for (n
= 0; n
< loop
->dimen
; n
++)
4397 loop
->order
[dim
++] = n
;
4400 gcc_assert (dim
== loop
->dimen
);
4411 tree base_type
= gfc_typenode_for_spec (&dest_expr
->ts
);
4412 if (GFC_ARRAY_TYPE_P (base_type
)
4413 || GFC_DESCRIPTOR_TYPE_P (base_type
))
4414 base_type
= gfc_get_element_type (base_type
);
4415 loop
->temp_ss
= gfc_get_temp_ss (base_type
, dest
->info
->string_length
,
4417 gfc_add_ss_to_loop (loop
, loop
->temp_ss
);
4420 loop
->temp_ss
= NULL
;
4424 /* Browse through each array's information from the scalarizer and set the loop
4425 bounds according to the "best" one (per dimension), i.e. the one which
4426 provides the most information (constant bounds, shape, etc.). */
4429 set_loop_bounds (gfc_loopinfo
*loop
)
4431 int n
, dim
, spec_dim
;
4432 gfc_array_info
*info
;
4433 gfc_array_info
*specinfo
;
4437 bool dynamic
[GFC_MAX_DIMENSIONS
];
4440 bool nonoptional_arr
;
4442 loopspec
= loop
->specloop
;
4445 for (n
= 0; n
< loop
->dimen
; n
++)
4450 /* If there are both optional and nonoptional array arguments, scalarize
4451 over the nonoptional; otherwise, it does not matter as then all
4452 (optional) arrays have to be present per F2008, 125.2.12p3(6). */
4454 nonoptional_arr
= false;
4456 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
4457 if (ss
->info
->type
!= GFC_SS_SCALAR
&& ss
->info
->type
!= GFC_SS_TEMP
4458 && ss
->info
->type
!= GFC_SS_REFERENCE
&& !ss
->info
->can_be_null_ref
)
4459 nonoptional_arr
= true;
4461 /* We use one SS term, and use that to determine the bounds of the
4462 loop for this dimension. We try to pick the simplest term. */
4463 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
4465 gfc_ss_type ss_type
;
4467 ss_type
= ss
->info
->type
;
4468 if (ss_type
== GFC_SS_SCALAR
4469 || ss_type
== GFC_SS_TEMP
4470 || ss_type
== GFC_SS_REFERENCE
4471 || (ss
->info
->can_be_null_ref
&& nonoptional_arr
))
4474 info
= &ss
->info
->data
.array
;
4477 if (loopspec
[n
] != NULL
)
4479 specinfo
= &loopspec
[n
]->info
->data
.array
;
4480 spec_dim
= loopspec
[n
]->dim
[n
];
4484 /* Silence uninitialized warnings. */
4491 gcc_assert (info
->shape
[dim
]);
4492 /* The frontend has worked out the size for us. */
4495 || !integer_zerop (specinfo
->start
[spec_dim
]))
4496 /* Prefer zero-based descriptors if possible. */
4501 if (ss_type
== GFC_SS_CONSTRUCTOR
)
4503 gfc_constructor_base base
;
4504 /* An unknown size constructor will always be rank one.
4505 Higher rank constructors will either have known shape,
4506 or still be wrapped in a call to reshape. */
4507 gcc_assert (loop
->dimen
== 1);
4509 /* Always prefer to use the constructor bounds if the size
4510 can be determined at compile time. Prefer not to otherwise,
4511 since the general case involves realloc, and it's better to
4512 avoid that overhead if possible. */
4513 base
= ss
->info
->expr
->value
.constructor
;
4514 dynamic
[n
] = gfc_get_array_constructor_size (&i
, base
);
4515 if (!dynamic
[n
] || !loopspec
[n
])
4520 /* Avoid using an allocatable lhs in an assignment, since
4521 there might be a reallocation coming. */
4522 if (loopspec
[n
] && ss
->is_alloc_lhs
)
4527 /* Criteria for choosing a loop specifier (most important first):
4528 doesn't need realloc
4534 else if (loopspec
[n
]->info
->type
== GFC_SS_CONSTRUCTOR
&& dynamic
[n
])
4536 else if (integer_onep (info
->stride
[dim
])
4537 && !integer_onep (specinfo
->stride
[spec_dim
]))
4539 else if (INTEGER_CST_P (info
->stride
[dim
])
4540 && !INTEGER_CST_P (specinfo
->stride
[spec_dim
]))
4542 else if (INTEGER_CST_P (info
->start
[dim
])
4543 && !INTEGER_CST_P (specinfo
->start
[spec_dim
])
4544 && integer_onep (info
->stride
[dim
])
4545 == integer_onep (specinfo
->stride
[spec_dim
])
4546 && INTEGER_CST_P (info
->stride
[dim
])
4547 == INTEGER_CST_P (specinfo
->stride
[spec_dim
]))
4549 /* We don't work out the upper bound.
4550 else if (INTEGER_CST_P (info->finish[n])
4551 && ! INTEGER_CST_P (specinfo->finish[n]))
4552 loopspec[n] = ss; */
4555 /* We should have found the scalarization loop specifier. If not,
4557 gcc_assert (loopspec
[n
]);
4559 info
= &loopspec
[n
]->info
->data
.array
;
4560 dim
= loopspec
[n
]->dim
[n
];
4562 /* Set the extents of this range. */
4563 cshape
= info
->shape
;
4564 if (cshape
&& INTEGER_CST_P (info
->start
[dim
])
4565 && INTEGER_CST_P (info
->stride
[dim
]))
4567 loop
->from
[n
] = info
->start
[dim
];
4568 mpz_set (i
, cshape
[get_array_ref_dim_for_loop_dim (loopspec
[n
], n
)]);
4569 mpz_sub_ui (i
, i
, 1);
4570 /* To = from + (size - 1) * stride. */
4571 tmp
= gfc_conv_mpz_to_tree (i
, gfc_index_integer_kind
);
4572 if (!integer_onep (info
->stride
[dim
]))
4573 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
4574 gfc_array_index_type
, tmp
,
4576 loop
->to
[n
] = fold_build2_loc (input_location
, PLUS_EXPR
,
4577 gfc_array_index_type
,
4578 loop
->from
[n
], tmp
);
4582 loop
->from
[n
] = info
->start
[dim
];
4583 switch (loopspec
[n
]->info
->type
)
4585 case GFC_SS_CONSTRUCTOR
:
4586 /* The upper bound is calculated when we expand the
4588 gcc_assert (loop
->to
[n
] == NULL_TREE
);
4591 case GFC_SS_SECTION
:
4592 /* Use the end expression if it exists and is not constant,
4593 so that it is only evaluated once. */
4594 loop
->to
[n
] = info
->end
[dim
];
4597 case GFC_SS_FUNCTION
:
4598 /* The loop bound will be set when we generate the call. */
4599 gcc_assert (loop
->to
[n
] == NULL_TREE
);
4602 case GFC_SS_INTRINSIC
:
4604 gfc_expr
*expr
= loopspec
[n
]->info
->expr
;
4606 /* The {l,u}bound of an assumed rank. */
4607 gcc_assert ((expr
->value
.function
.isym
->id
== GFC_ISYM_LBOUND
4608 || expr
->value
.function
.isym
->id
== GFC_ISYM_UBOUND
)
4609 && expr
->value
.function
.actual
->next
->expr
== NULL
4610 && expr
->value
.function
.actual
->expr
->rank
== -1);
4612 loop
->to
[n
] = info
->end
[dim
];
4621 /* Transform everything so we have a simple incrementing variable. */
4622 if (integer_onep (info
->stride
[dim
]))
4623 info
->delta
[dim
] = gfc_index_zero_node
;
4626 /* Set the delta for this section. */
4627 info
->delta
[dim
] = gfc_evaluate_now (loop
->from
[n
], &loop
->pre
);
4628 /* Number of iterations is (end - start + step) / step.
4629 with start = 0, this simplifies to
4631 for (i = 0; i<=last; i++){...}; */
4632 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4633 gfc_array_index_type
, loop
->to
[n
],
4635 tmp
= fold_build2_loc (input_location
, FLOOR_DIV_EXPR
,
4636 gfc_array_index_type
, tmp
, info
->stride
[dim
]);
4637 tmp
= fold_build2_loc (input_location
, MAX_EXPR
, gfc_array_index_type
,
4638 tmp
, build_int_cst (gfc_array_index_type
, -1));
4639 loop
->to
[n
] = gfc_evaluate_now (tmp
, &loop
->pre
);
4640 /* Make the loop variable start at 0. */
4641 loop
->from
[n
] = gfc_index_zero_node
;
4646 for (loop
= loop
->nested
; loop
; loop
= loop
->next
)
4647 set_loop_bounds (loop
);
4651 /* Initialize the scalarization loop. Creates the loop variables. Determines
4652 the range of the loop variables. Creates a temporary if required.
4653 Also generates code for scalar expressions which have been
4654 moved outside the loop. */
4657 gfc_conv_loop_setup (gfc_loopinfo
* loop
, locus
* where
)
4662 set_loop_bounds (loop
);
4664 /* Add all the scalar code that can be taken out of the loops.
4665 This may include calculating the loop bounds, so do it before
4666 allocating the temporary. */
4667 gfc_add_loop_ss_code (loop
, loop
->ss
, false, where
);
4669 tmp_ss
= loop
->temp_ss
;
4670 /* If we want a temporary then create it. */
4673 gfc_ss_info
*tmp_ss_info
;
4675 tmp_ss_info
= tmp_ss
->info
;
4676 gcc_assert (tmp_ss_info
->type
== GFC_SS_TEMP
);
4677 gcc_assert (loop
->parent
== NULL
);
4679 /* Make absolutely sure that this is a complete type. */
4680 if (tmp_ss_info
->string_length
)
4681 tmp_ss_info
->data
.temp
.type
4682 = gfc_get_character_type_len_for_eltype
4683 (TREE_TYPE (tmp_ss_info
->data
.temp
.type
),
4684 tmp_ss_info
->string_length
);
4686 tmp
= tmp_ss_info
->data
.temp
.type
;
4687 memset (&tmp_ss_info
->data
.array
, 0, sizeof (gfc_array_info
));
4688 tmp_ss_info
->type
= GFC_SS_SECTION
;
4690 gcc_assert (tmp_ss
->dimen
!= 0);
4692 gfc_trans_create_temp_array (&loop
->pre
, &loop
->post
, tmp_ss
, tmp
,
4693 NULL_TREE
, false, true, false, where
);
4696 /* For array parameters we don't have loop variables, so don't calculate the
4698 if (!loop
->array_parameter
)
4699 gfc_set_delta (loop
);
4703 /* Calculates how to transform from loop variables to array indices for each
4704 array: once loop bounds are chosen, sets the difference (DELTA field) between
4705 loop bounds and array reference bounds, for each array info. */
4708 gfc_set_delta (gfc_loopinfo
*loop
)
4710 gfc_ss
*ss
, **loopspec
;
4711 gfc_array_info
*info
;
4715 loopspec
= loop
->specloop
;
4717 /* Calculate the translation from loop variables to array indices. */
4718 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
4720 gfc_ss_type ss_type
;
4722 ss_type
= ss
->info
->type
;
4723 if (ss_type
!= GFC_SS_SECTION
4724 && ss_type
!= GFC_SS_COMPONENT
4725 && ss_type
!= GFC_SS_CONSTRUCTOR
)
4728 info
= &ss
->info
->data
.array
;
4730 for (n
= 0; n
< ss
->dimen
; n
++)
4732 /* If we are specifying the range the delta is already set. */
4733 if (loopspec
[n
] != ss
)
4737 /* Calculate the offset relative to the loop variable.
4738 First multiply by the stride. */
4739 tmp
= loop
->from
[n
];
4740 if (!integer_onep (info
->stride
[dim
]))
4741 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
4742 gfc_array_index_type
,
4743 tmp
, info
->stride
[dim
]);
4745 /* Then subtract this from our starting value. */
4746 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4747 gfc_array_index_type
,
4748 info
->start
[dim
], tmp
);
4750 info
->delta
[dim
] = gfc_evaluate_now (tmp
, &loop
->pre
);
4755 for (loop
= loop
->nested
; loop
; loop
= loop
->next
)
4756 gfc_set_delta (loop
);
4760 /* Calculate the size of a given array dimension from the bounds. This
4761 is simply (ubound - lbound + 1) if this expression is positive
4762 or 0 if it is negative (pick either one if it is zero). Optionally
4763 (if or_expr is present) OR the (expression != 0) condition to it. */
4766 gfc_conv_array_extent_dim (tree lbound
, tree ubound
, tree
* or_expr
)
4771 /* Calculate (ubound - lbound + 1). */
4772 res
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
4774 res
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
, res
,
4775 gfc_index_one_node
);
4777 /* Check whether the size for this dimension is negative. */
4778 cond
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
, res
,
4779 gfc_index_zero_node
);
4780 res
= fold_build3_loc (input_location
, COND_EXPR
, gfc_array_index_type
, cond
,
4781 gfc_index_zero_node
, res
);
4783 /* Build OR expression. */
4785 *or_expr
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
4786 boolean_type_node
, *or_expr
, cond
);
4792 /* For an array descriptor, get the total number of elements. This is just
4793 the product of the extents along from_dim to to_dim. */
4796 gfc_conv_descriptor_size_1 (tree desc
, int from_dim
, int to_dim
)
4801 res
= gfc_index_one_node
;
4803 for (dim
= from_dim
; dim
< to_dim
; ++dim
)
4809 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[dim
]);
4810 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[dim
]);
4812 extent
= gfc_conv_array_extent_dim (lbound
, ubound
, NULL
);
4813 res
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4821 /* Full size of an array. */
4824 gfc_conv_descriptor_size (tree desc
, int rank
)
4826 return gfc_conv_descriptor_size_1 (desc
, 0, rank
);
4830 /* Size of a coarray for all dimensions but the last. */
4833 gfc_conv_descriptor_cosize (tree desc
, int rank
, int corank
)
4835 return gfc_conv_descriptor_size_1 (desc
, rank
, rank
+ corank
- 1);
4839 /* Fills in an array descriptor, and returns the size of the array.
4840 The size will be a simple_val, ie a variable or a constant. Also
4841 calculates the offset of the base. The pointer argument overflow,
4842 which should be of integer type, will increase in value if overflow
4843 occurs during the size calculation. Returns the size of the array.
4847 for (n = 0; n < rank; n++)
4849 a.lbound[n] = specified_lower_bound;
4850 offset = offset + a.lbond[n] * stride;
4852 a.ubound[n] = specified_upper_bound;
4853 a.stride[n] = stride;
4854 size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
4855 overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
4856 stride = stride * size;
4858 for (n = rank; n < rank+corank; n++)
4859 (Set lcobound/ucobound as above.)
4860 element_size = sizeof (array element);
4863 stride = (size_t) stride;
4864 overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
4865 stride = stride * element_size;
4871 gfc_array_init_size (tree descriptor
, int rank
, int corank
, tree
* poffset
,
4872 gfc_expr
** lower
, gfc_expr
** upper
, stmtblock_t
* pblock
,
4873 stmtblock_t
* descriptor_block
, tree
* overflow
,
4874 tree expr3_elem_size
, tree
*nelems
, gfc_expr
*expr3
,
4888 stmtblock_t thenblock
;
4889 stmtblock_t elseblock
;
4894 type
= TREE_TYPE (descriptor
);
4896 stride
= gfc_index_one_node
;
4897 offset
= gfc_index_zero_node
;
4899 /* Set the dtype. */
4900 tmp
= gfc_conv_descriptor_dtype (descriptor
);
4901 gfc_add_modify (descriptor_block
, tmp
, gfc_get_dtype (TREE_TYPE (descriptor
)));
4903 or_expr
= boolean_false_node
;
4905 for (n
= 0; n
< rank
; n
++)
4910 /* We have 3 possibilities for determining the size of the array:
4911 lower == NULL => lbound = 1, ubound = upper[n]
4912 upper[n] = NULL => lbound = 1, ubound = lower[n]
4913 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
4916 /* Set lower bound. */
4917 gfc_init_se (&se
, NULL
);
4919 se
.expr
= gfc_index_one_node
;
4922 gcc_assert (lower
[n
]);
4925 gfc_conv_expr_type (&se
, lower
[n
], gfc_array_index_type
);
4926 gfc_add_block_to_block (pblock
, &se
.pre
);
4930 se
.expr
= gfc_index_one_node
;
4934 gfc_conv_descriptor_lbound_set (descriptor_block
, descriptor
,
4935 gfc_rank_cst
[n
], se
.expr
);
4936 conv_lbound
= se
.expr
;
4938 /* Work out the offset for this component. */
4939 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4941 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
4942 gfc_array_index_type
, offset
, tmp
);
4944 /* Set upper bound. */
4945 gfc_init_se (&se
, NULL
);
4946 gcc_assert (ubound
);
4947 gfc_conv_expr_type (&se
, ubound
, gfc_array_index_type
);
4948 gfc_add_block_to_block (pblock
, &se
.pre
);
4950 gfc_conv_descriptor_ubound_set (descriptor_block
, descriptor
,
4951 gfc_rank_cst
[n
], se
.expr
);
4952 conv_ubound
= se
.expr
;
4954 /* Store the stride. */
4955 gfc_conv_descriptor_stride_set (descriptor_block
, descriptor
,
4956 gfc_rank_cst
[n
], stride
);
4958 /* Calculate size and check whether extent is negative. */
4959 size
= gfc_conv_array_extent_dim (conv_lbound
, conv_ubound
, &or_expr
);
4960 size
= gfc_evaluate_now (size
, pblock
);
4962 /* Check whether multiplying the stride by the number of
4963 elements in this dimension would overflow. We must also check
4964 whether the current dimension has zero size in order to avoid
4967 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
4968 gfc_array_index_type
,
4969 fold_convert (gfc_array_index_type
,
4970 TYPE_MAX_VALUE (gfc_array_index_type
)),
4972 cond
= gfc_unlikely (fold_build2_loc (input_location
, LT_EXPR
,
4973 boolean_type_node
, tmp
, stride
));
4974 tmp
= fold_build3_loc (input_location
, COND_EXPR
, integer_type_node
, cond
,
4975 integer_one_node
, integer_zero_node
);
4976 cond
= gfc_unlikely (fold_build2_loc (input_location
, EQ_EXPR
,
4977 boolean_type_node
, size
,
4978 gfc_index_zero_node
));
4979 tmp
= fold_build3_loc (input_location
, COND_EXPR
, integer_type_node
, cond
,
4980 integer_zero_node
, tmp
);
4981 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, integer_type_node
,
4983 *overflow
= gfc_evaluate_now (tmp
, pblock
);
4985 /* Multiply the stride by the number of elements in this dimension. */
4986 stride
= fold_build2_loc (input_location
, MULT_EXPR
,
4987 gfc_array_index_type
, stride
, size
);
4988 stride
= gfc_evaluate_now (stride
, pblock
);
4991 for (n
= rank
; n
< rank
+ corank
; n
++)
4995 /* Set lower bound. */
4996 gfc_init_se (&se
, NULL
);
4997 if (lower
== NULL
|| lower
[n
] == NULL
)
4999 gcc_assert (n
== rank
+ corank
- 1);
5000 se
.expr
= gfc_index_one_node
;
5004 if (ubound
|| n
== rank
+ corank
- 1)
5006 gfc_conv_expr_type (&se
, lower
[n
], gfc_array_index_type
);
5007 gfc_add_block_to_block (pblock
, &se
.pre
);
5011 se
.expr
= gfc_index_one_node
;
5015 gfc_conv_descriptor_lbound_set (descriptor_block
, descriptor
,
5016 gfc_rank_cst
[n
], se
.expr
);
5018 if (n
< rank
+ corank
- 1)
5020 gfc_init_se (&se
, NULL
);
5021 gcc_assert (ubound
);
5022 gfc_conv_expr_type (&se
, ubound
, gfc_array_index_type
);
5023 gfc_add_block_to_block (pblock
, &se
.pre
);
5024 gfc_conv_descriptor_ubound_set (descriptor_block
, descriptor
,
5025 gfc_rank_cst
[n
], se
.expr
);
5029 /* The stride is the number of elements in the array, so multiply by the
5030 size of an element to get the total size. Obviously, if there is a
5031 SOURCE expression (expr3) we must use its element size. */
5032 if (expr3_elem_size
!= NULL_TREE
)
5033 tmp
= expr3_elem_size
;
5034 else if (expr3
!= NULL
)
5036 if (expr3
->ts
.type
== BT_CLASS
)
5039 gfc_expr
*sz
= gfc_copy_expr (expr3
);
5040 gfc_add_vptr_component (sz
);
5041 gfc_add_size_component (sz
);
5042 gfc_init_se (&se_sz
, NULL
);
5043 gfc_conv_expr (&se_sz
, sz
);
5049 tmp
= gfc_typenode_for_spec (&expr3
->ts
);
5050 tmp
= TYPE_SIZE_UNIT (tmp
);
5053 else if (ts
->type
!= BT_UNKNOWN
&& ts
->type
!= BT_CHARACTER
)
5054 /* FIXME: Properly handle characters. See PR 57456. */
5055 tmp
= TYPE_SIZE_UNIT (gfc_typenode_for_spec (ts
));
5057 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
5059 /* Convert to size_t. */
5060 element_size
= fold_convert (size_type_node
, tmp
);
5063 return element_size
;
5065 *nelems
= gfc_evaluate_now (stride
, pblock
);
5066 stride
= fold_convert (size_type_node
, stride
);
5068 /* First check for overflow. Since an array of type character can
5069 have zero element_size, we must check for that before
5071 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
5073 TYPE_MAX_VALUE (size_type_node
), element_size
);
5074 cond
= gfc_unlikely (fold_build2_loc (input_location
, LT_EXPR
,
5075 boolean_type_node
, tmp
, stride
));
5076 tmp
= fold_build3_loc (input_location
, COND_EXPR
, integer_type_node
, cond
,
5077 integer_one_node
, integer_zero_node
);
5078 cond
= gfc_unlikely (fold_build2_loc (input_location
, EQ_EXPR
,
5079 boolean_type_node
, element_size
,
5080 build_int_cst (size_type_node
, 0)));
5081 tmp
= fold_build3_loc (input_location
, COND_EXPR
, integer_type_node
, cond
,
5082 integer_zero_node
, tmp
);
5083 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, integer_type_node
,
5085 *overflow
= gfc_evaluate_now (tmp
, pblock
);
5087 size
= fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
5088 stride
, element_size
);
5090 if (poffset
!= NULL
)
5092 offset
= gfc_evaluate_now (offset
, pblock
);
5096 if (integer_zerop (or_expr
))
5098 if (integer_onep (or_expr
))
5099 return build_int_cst (size_type_node
, 0);
5101 var
= gfc_create_var (TREE_TYPE (size
), "size");
5102 gfc_start_block (&thenblock
);
5103 gfc_add_modify (&thenblock
, var
, build_int_cst (size_type_node
, 0));
5104 thencase
= gfc_finish_block (&thenblock
);
5106 gfc_start_block (&elseblock
);
5107 gfc_add_modify (&elseblock
, var
, size
);
5108 elsecase
= gfc_finish_block (&elseblock
);
5110 tmp
= gfc_evaluate_now (or_expr
, pblock
);
5111 tmp
= build3_v (COND_EXPR
, tmp
, thencase
, elsecase
);
5112 gfc_add_expr_to_block (pblock
, tmp
);
5118 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
5119 the work for an ALLOCATE statement. */
5123 gfc_array_allocate (gfc_se
* se
, gfc_expr
* expr
, tree status
, tree errmsg
,
5124 tree errlen
, tree label_finish
, tree expr3_elem_size
,
5125 tree
*nelems
, gfc_expr
*expr3
, gfc_typespec
*ts
)
5129 tree offset
= NULL_TREE
;
5130 tree token
= NULL_TREE
;
5133 tree error
= NULL_TREE
;
5134 tree overflow
; /* Boolean storing whether size calculation overflows. */
5135 tree var_overflow
= NULL_TREE
;
5137 tree set_descriptor
;
5138 stmtblock_t set_descriptor_block
;
5139 stmtblock_t elseblock
;
5142 gfc_ref
*ref
, *prev_ref
= NULL
;
5143 bool allocatable
, coarray
, dimension
;
5147 /* Find the last reference in the chain. */
5148 while (ref
&& ref
->next
!= NULL
)
5150 gcc_assert (ref
->type
!= REF_ARRAY
|| ref
->u
.ar
.type
== AR_ELEMENT
5151 || (ref
->u
.ar
.dimen
== 0 && ref
->u
.ar
.codimen
> 0));
5156 if (ref
== NULL
|| ref
->type
!= REF_ARRAY
)
5161 allocatable
= expr
->symtree
->n
.sym
->attr
.allocatable
;
5162 coarray
= expr
->symtree
->n
.sym
->attr
.codimension
;
5163 dimension
= expr
->symtree
->n
.sym
->attr
.dimension
;
5167 allocatable
= prev_ref
->u
.c
.component
->attr
.allocatable
;
5168 coarray
= prev_ref
->u
.c
.component
->attr
.codimension
;
5169 dimension
= prev_ref
->u
.c
.component
->attr
.dimension
;
5173 gcc_assert (coarray
);
5175 /* Figure out the size of the array. */
5176 switch (ref
->u
.ar
.type
)
5182 upper
= ref
->u
.ar
.start
;
5188 lower
= ref
->u
.ar
.start
;
5189 upper
= ref
->u
.ar
.end
;
5193 gcc_assert (ref
->u
.ar
.as
->type
== AS_EXPLICIT
);
5195 lower
= ref
->u
.ar
.as
->lower
;
5196 upper
= ref
->u
.ar
.as
->upper
;
5204 overflow
= integer_zero_node
;
5206 gfc_init_block (&set_descriptor_block
);
5207 size
= gfc_array_init_size (se
->expr
, ref
->u
.ar
.as
->rank
,
5208 ref
->u
.ar
.as
->corank
, &offset
, lower
, upper
,
5209 &se
->pre
, &set_descriptor_block
, &overflow
,
5210 expr3_elem_size
, nelems
, expr3
, ts
);
5214 var_overflow
= gfc_create_var (integer_type_node
, "overflow");
5215 gfc_add_modify (&se
->pre
, var_overflow
, overflow
);
5217 if (status
== NULL_TREE
)
5219 /* Generate the block of code handling overflow. */
5220 msg
= gfc_build_addr_expr (pchar_type_node
,
5221 gfc_build_localized_cstring_const
5222 ("Integer overflow when calculating the amount of "
5223 "memory to allocate"));
5224 error
= build_call_expr_loc (input_location
,
5225 gfor_fndecl_runtime_error
, 1, msg
);
5229 tree status_type
= TREE_TYPE (status
);
5230 stmtblock_t set_status_block
;
5232 gfc_start_block (&set_status_block
);
5233 gfc_add_modify (&set_status_block
, status
,
5234 build_int_cst (status_type
, LIBERROR_ALLOCATION
));
5235 error
= gfc_finish_block (&set_status_block
);
5239 gfc_start_block (&elseblock
);
5241 /* Allocate memory to store the data. */
5242 if (POINTER_TYPE_P (TREE_TYPE (se
->expr
)))
5243 se
->expr
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
5245 pointer
= gfc_conv_descriptor_data_get (se
->expr
);
5246 STRIP_NOPS (pointer
);
5248 if (coarray
&& gfc_option
.coarray
== GFC_FCOARRAY_LIB
)
5249 token
= gfc_build_addr_expr (NULL_TREE
,
5250 gfc_conv_descriptor_token (se
->expr
));
5252 /* The allocatable variant takes the old pointer as first argument. */
5254 gfc_allocate_allocatable (&elseblock
, pointer
, size
, token
,
5255 status
, errmsg
, errlen
, label_finish
, expr
);
5257 gfc_allocate_using_malloc (&elseblock
, pointer
, size
, status
);
5261 cond
= gfc_unlikely (fold_build2_loc (input_location
, NE_EXPR
,
5262 boolean_type_node
, var_overflow
, integer_zero_node
));
5263 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5264 error
, gfc_finish_block (&elseblock
));
5267 tmp
= gfc_finish_block (&elseblock
);
5269 gfc_add_expr_to_block (&se
->pre
, tmp
);
5271 /* Update the array descriptors. */
5273 gfc_conv_descriptor_offset_set (&set_descriptor_block
, se
->expr
, offset
);
5275 set_descriptor
= gfc_finish_block (&set_descriptor_block
);
5276 if (status
!= NULL_TREE
)
5278 cond
= fold_build2_loc (input_location
, EQ_EXPR
,
5279 boolean_type_node
, status
,
5280 build_int_cst (TREE_TYPE (status
), 0));
5281 gfc_add_expr_to_block (&se
->pre
,
5282 fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
5283 gfc_likely (cond
), set_descriptor
,
5284 build_empty_stmt (input_location
)));
5287 gfc_add_expr_to_block (&se
->pre
, set_descriptor
);
5289 if ((expr
->ts
.type
== BT_DERIVED
)
5290 && expr
->ts
.u
.derived
->attr
.alloc_comp
)
5292 tmp
= gfc_nullify_alloc_comp (expr
->ts
.u
.derived
, se
->expr
,
5293 ref
->u
.ar
.as
->rank
);
5294 gfc_add_expr_to_block (&se
->pre
, tmp
);
5301 /* Deallocate an array variable. Also used when an allocated variable goes
5306 gfc_array_deallocate (tree descriptor
, tree pstat
, tree errmsg
, tree errlen
,
5307 tree label_finish
, gfc_expr
* expr
)
5312 bool coarray
= gfc_is_coarray (expr
);
5314 gfc_start_block (&block
);
5316 /* Get a pointer to the data. */
5317 var
= gfc_conv_descriptor_data_get (descriptor
);
5320 /* Parameter is the address of the data component. */
5321 tmp
= gfc_deallocate_with_status (coarray
? descriptor
: var
, pstat
, errmsg
,
5322 errlen
, label_finish
, false, expr
, coarray
);
5323 gfc_add_expr_to_block (&block
, tmp
);
5325 /* Zero the data pointer; only for coarrays an error can occur and then
5326 the allocation status may not be changed. */
5327 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
5328 var
, build_int_cst (TREE_TYPE (var
), 0));
5329 if (pstat
!= NULL_TREE
&& coarray
&& gfc_option
.coarray
== GFC_FCOARRAY_LIB
)
5332 tree stat
= build_fold_indirect_ref_loc (input_location
, pstat
);
5334 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
5335 stat
, build_int_cst (TREE_TYPE (stat
), 0));
5336 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
5337 cond
, tmp
, build_empty_stmt (input_location
));
5340 gfc_add_expr_to_block (&block
, tmp
);
5342 return gfc_finish_block (&block
);
5346 /* Create an array constructor from an initialization expression.
5347 We assume the frontend already did any expansions and conversions. */
5350 gfc_conv_array_initializer (tree type
, gfc_expr
* expr
)
5356 unsigned HOST_WIDE_INT lo
;
5358 vec
<constructor_elt
, va_gc
> *v
= NULL
;
5360 if (expr
->expr_type
== EXPR_VARIABLE
5361 && expr
->symtree
->n
.sym
->attr
.flavor
== FL_PARAMETER
5362 && expr
->symtree
->n
.sym
->value
)
5363 expr
= expr
->symtree
->n
.sym
->value
;
5365 switch (expr
->expr_type
)
5368 case EXPR_STRUCTURE
:
5369 /* A single scalar or derived type value. Create an array with all
5370 elements equal to that value. */
5371 gfc_init_se (&se
, NULL
);
5373 if (expr
->expr_type
== EXPR_CONSTANT
)
5374 gfc_conv_constant (&se
, expr
);
5376 gfc_conv_structure (&se
, expr
, 1);
5378 tmp
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
5379 gcc_assert (tmp
&& INTEGER_CST_P (tmp
));
5380 hi
= TREE_INT_CST_HIGH (tmp
);
5381 lo
= TREE_INT_CST_LOW (tmp
);
5385 /* This will probably eat buckets of memory for large arrays. */
5386 while (hi
!= 0 || lo
!= 0)
5388 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, se
.expr
);
5396 /* Create a vector of all the elements. */
5397 for (c
= gfc_constructor_first (expr
->value
.constructor
);
5398 c
; c
= gfc_constructor_next (c
))
5402 /* Problems occur when we get something like
5403 integer :: a(lots) = (/(i, i=1, lots)/) */
5404 gfc_fatal_error ("The number of elements in the array constructor "
5405 "at %L requires an increase of the allowed %d "
5406 "upper limit. See -fmax-array-constructor "
5407 "option", &expr
->where
,
5408 gfc_option
.flag_max_array_constructor
);
5411 if (mpz_cmp_si (c
->offset
, 0) != 0)
5412 index
= gfc_conv_mpz_to_tree (c
->offset
, gfc_index_integer_kind
);
5416 if (mpz_cmp_si (c
->repeat
, 1) > 0)
5422 mpz_add (maxval
, c
->offset
, c
->repeat
);
5423 mpz_sub_ui (maxval
, maxval
, 1);
5424 tmp2
= gfc_conv_mpz_to_tree (maxval
, gfc_index_integer_kind
);
5425 if (mpz_cmp_si (c
->offset
, 0) != 0)
5427 mpz_add_ui (maxval
, c
->offset
, 1);
5428 tmp1
= gfc_conv_mpz_to_tree (maxval
, gfc_index_integer_kind
);
5431 tmp1
= gfc_conv_mpz_to_tree (c
->offset
, gfc_index_integer_kind
);
5433 range
= fold_build2 (RANGE_EXPR
, gfc_array_index_type
, tmp1
, tmp2
);
5439 gfc_init_se (&se
, NULL
);
5440 switch (c
->expr
->expr_type
)
5443 gfc_conv_constant (&se
, c
->expr
);
5446 case EXPR_STRUCTURE
:
5447 gfc_conv_structure (&se
, c
->expr
, 1);
5451 /* Catch those occasional beasts that do not simplify
5452 for one reason or another, assuming that if they are
5453 standard defying the frontend will catch them. */
5454 gfc_conv_expr (&se
, c
->expr
);
5458 if (range
== NULL_TREE
)
5459 CONSTRUCTOR_APPEND_ELT (v
, index
, se
.expr
);
5462 if (index
!= NULL_TREE
)
5463 CONSTRUCTOR_APPEND_ELT (v
, index
, se
.expr
);
5464 CONSTRUCTOR_APPEND_ELT (v
, range
, se
.expr
);
5470 return gfc_build_null_descriptor (type
);
5476 /* Create a constructor from the list of elements. */
5477 tmp
= build_constructor (type
, v
);
5478 TREE_CONSTANT (tmp
) = 1;
5483 /* Generate code to evaluate non-constant coarray cobounds. */
5486 gfc_trans_array_cobounds (tree type
, stmtblock_t
* pblock
,
5487 const gfc_symbol
*sym
)
5497 for (dim
= as
->rank
; dim
< as
->rank
+ as
->corank
; dim
++)
5499 /* Evaluate non-constant array bound expressions. */
5500 lbound
= GFC_TYPE_ARRAY_LBOUND (type
, dim
);
5501 if (as
->lower
[dim
] && !INTEGER_CST_P (lbound
))
5503 gfc_init_se (&se
, NULL
);
5504 gfc_conv_expr_type (&se
, as
->lower
[dim
], gfc_array_index_type
);
5505 gfc_add_block_to_block (pblock
, &se
.pre
);
5506 gfc_add_modify (pblock
, lbound
, se
.expr
);
5508 ubound
= GFC_TYPE_ARRAY_UBOUND (type
, dim
);
5509 if (as
->upper
[dim
] && !INTEGER_CST_P (ubound
))
5511 gfc_init_se (&se
, NULL
);
5512 gfc_conv_expr_type (&se
, as
->upper
[dim
], gfc_array_index_type
);
5513 gfc_add_block_to_block (pblock
, &se
.pre
);
5514 gfc_add_modify (pblock
, ubound
, se
.expr
);
5520 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
5521 returns the size (in elements) of the array. */
5524 gfc_trans_array_bounds (tree type
, gfc_symbol
* sym
, tree
* poffset
,
5525 stmtblock_t
* pblock
)
5540 size
= gfc_index_one_node
;
5541 offset
= gfc_index_zero_node
;
5542 for (dim
= 0; dim
< as
->rank
; dim
++)
5544 /* Evaluate non-constant array bound expressions. */
5545 lbound
= GFC_TYPE_ARRAY_LBOUND (type
, dim
);
5546 if (as
->lower
[dim
] && !INTEGER_CST_P (lbound
))
5548 gfc_init_se (&se
, NULL
);
5549 gfc_conv_expr_type (&se
, as
->lower
[dim
], gfc_array_index_type
);
5550 gfc_add_block_to_block (pblock
, &se
.pre
);
5551 gfc_add_modify (pblock
, lbound
, se
.expr
);
5553 ubound
= GFC_TYPE_ARRAY_UBOUND (type
, dim
);
5554 if (as
->upper
[dim
] && !INTEGER_CST_P (ubound
))
5556 gfc_init_se (&se
, NULL
);
5557 gfc_conv_expr_type (&se
, as
->upper
[dim
], gfc_array_index_type
);
5558 gfc_add_block_to_block (pblock
, &se
.pre
);
5559 gfc_add_modify (pblock
, ubound
, se
.expr
);
5561 /* The offset of this dimension. offset = offset - lbound * stride. */
5562 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
5564 offset
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
5567 /* The size of this dimension, and the stride of the next. */
5568 if (dim
+ 1 < as
->rank
)
5569 stride
= GFC_TYPE_ARRAY_STRIDE (type
, dim
+ 1);
5571 stride
= GFC_TYPE_ARRAY_SIZE (type
);
5573 if (ubound
!= NULL_TREE
&& !(stride
&& INTEGER_CST_P (stride
)))
5575 /* Calculate stride = size * (ubound + 1 - lbound). */
5576 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
5577 gfc_array_index_type
,
5578 gfc_index_one_node
, lbound
);
5579 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
5580 gfc_array_index_type
, ubound
, tmp
);
5581 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
5582 gfc_array_index_type
, size
, tmp
);
5584 gfc_add_modify (pblock
, stride
, tmp
);
5586 stride
= gfc_evaluate_now (tmp
, pblock
);
5588 /* Make sure that negative size arrays are translated
5589 to being zero size. */
5590 tmp
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
5591 stride
, gfc_index_zero_node
);
5592 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
5593 gfc_array_index_type
, tmp
,
5594 stride
, gfc_index_zero_node
);
5595 gfc_add_modify (pblock
, stride
, tmp
);
5601 gfc_trans_array_cobounds (type
, pblock
, sym
);
5602 gfc_trans_vla_type_sizes (sym
, pblock
);
5609 /* Generate code to initialize/allocate an array variable. */
5612 gfc_trans_auto_array_allocation (tree decl
, gfc_symbol
* sym
,
5613 gfc_wrapped_block
* block
)
5617 tree tmp
= NULL_TREE
;
5624 gcc_assert (!(sym
->attr
.pointer
|| sym
->attr
.allocatable
));
5626 /* Do nothing for USEd variables. */
5627 if (sym
->attr
.use_assoc
)
5630 type
= TREE_TYPE (decl
);
5631 gcc_assert (GFC_ARRAY_TYPE_P (type
));
5632 onstack
= TREE_CODE (type
) != POINTER_TYPE
;
5634 gfc_init_block (&init
);
5636 /* Evaluate character string length. */
5637 if (sym
->ts
.type
== BT_CHARACTER
5638 && onstack
&& !INTEGER_CST_P (sym
->ts
.u
.cl
->backend_decl
))
5640 gfc_conv_string_length (sym
->ts
.u
.cl
, NULL
, &init
);
5642 gfc_trans_vla_type_sizes (sym
, &init
);
5644 /* Emit a DECL_EXPR for this variable, which will cause the
5645 gimplifier to allocate storage, and all that good stuff. */
5646 tmp
= fold_build1_loc (input_location
, DECL_EXPR
, TREE_TYPE (decl
), decl
);
5647 gfc_add_expr_to_block (&init
, tmp
);
5652 gfc_add_init_cleanup (block
, gfc_finish_block (&init
), NULL_TREE
);
5656 type
= TREE_TYPE (type
);
5658 gcc_assert (!sym
->attr
.use_assoc
);
5659 gcc_assert (!TREE_STATIC (decl
));
5660 gcc_assert (!sym
->module
);
5662 if (sym
->ts
.type
== BT_CHARACTER
5663 && !INTEGER_CST_P (sym
->ts
.u
.cl
->backend_decl
))
5664 gfc_conv_string_length (sym
->ts
.u
.cl
, NULL
, &init
);
5666 size
= gfc_trans_array_bounds (type
, sym
, &offset
, &init
);
5668 /* Don't actually allocate space for Cray Pointees. */
5669 if (sym
->attr
.cray_pointee
)
5671 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
5672 gfc_add_modify (&init
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
5674 gfc_add_init_cleanup (block
, gfc_finish_block (&init
), NULL_TREE
);
5678 if (gfc_option
.flag_stack_arrays
)
5680 gcc_assert (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
);
5681 space
= build_decl (sym
->declared_at
.lb
->location
,
5682 VAR_DECL
, create_tmp_var_name ("A"),
5683 TREE_TYPE (TREE_TYPE (decl
)));
5684 gfc_trans_vla_type_sizes (sym
, &init
);
5688 /* The size is the number of elements in the array, so multiply by the
5689 size of an element to get the total size. */
5690 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
5691 size
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
5692 size
, fold_convert (gfc_array_index_type
, tmp
));
5694 /* Allocate memory to hold the data. */
5695 tmp
= gfc_call_malloc (&init
, TREE_TYPE (decl
), size
);
5696 gfc_add_modify (&init
, decl
, tmp
);
5698 /* Free the temporary. */
5699 tmp
= gfc_call_free (convert (pvoid_type_node
, decl
));
5703 /* Set offset of the array. */
5704 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
5705 gfc_add_modify (&init
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
5707 /* Automatic arrays should not have initializers. */
5708 gcc_assert (!sym
->value
);
5710 inittree
= gfc_finish_block (&init
);
5717 /* Don't create new scope, emit the DECL_EXPR in exactly the scope
5718 where also space is located. */
5719 gfc_init_block (&init
);
5720 tmp
= fold_build1_loc (input_location
, DECL_EXPR
,
5721 TREE_TYPE (space
), space
);
5722 gfc_add_expr_to_block (&init
, tmp
);
5723 addr
= fold_build1_loc (sym
->declared_at
.lb
->location
,
5724 ADDR_EXPR
, TREE_TYPE (decl
), space
);
5725 gfc_add_modify (&init
, decl
, addr
);
5726 gfc_add_init_cleanup (block
, gfc_finish_block (&init
), NULL_TREE
);
5729 gfc_add_init_cleanup (block
, inittree
, tmp
);
5733 /* Generate entry and exit code for g77 calling convention arrays. */
5736 gfc_trans_g77_array (gfc_symbol
* sym
, gfc_wrapped_block
* block
)
5746 gfc_save_backend_locus (&loc
);
5747 gfc_set_backend_locus (&sym
->declared_at
);
5749 /* Descriptor type. */
5750 parm
= sym
->backend_decl
;
5751 type
= TREE_TYPE (parm
);
5752 gcc_assert (GFC_ARRAY_TYPE_P (type
));
5754 gfc_start_block (&init
);
5756 if (sym
->ts
.type
== BT_CHARACTER
5757 && TREE_CODE (sym
->ts
.u
.cl
->backend_decl
) == VAR_DECL
)
5758 gfc_conv_string_length (sym
->ts
.u
.cl
, NULL
, &init
);
5760 /* Evaluate the bounds of the array. */
5761 gfc_trans_array_bounds (type
, sym
, &offset
, &init
);
5763 /* Set the offset. */
5764 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
5765 gfc_add_modify (&init
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
5767 /* Set the pointer itself if we aren't using the parameter directly. */
5768 if (TREE_CODE (parm
) != PARM_DECL
)
5770 tmp
= convert (TREE_TYPE (parm
), GFC_DECL_SAVED_DESCRIPTOR (parm
));
5771 gfc_add_modify (&init
, parm
, tmp
);
5773 stmt
= gfc_finish_block (&init
);
5775 gfc_restore_backend_locus (&loc
);
5777 /* Add the initialization code to the start of the function. */
5779 if (sym
->attr
.optional
|| sym
->attr
.not_always_present
)
5781 tmp
= gfc_conv_expr_present (sym
);
5782 stmt
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt (input_location
));
5785 gfc_add_init_cleanup (block
, stmt
, NULL_TREE
);
5789 /* Modify the descriptor of an array parameter so that it has the
5790 correct lower bound. Also move the upper bound accordingly.
5791 If the array is not packed, it will be copied into a temporary.
5792 For each dimension we set the new lower and upper bounds. Then we copy the
5793 stride and calculate the offset for this dimension. We also work out
5794 what the stride of a packed array would be, and see it the two match.
5795 If the array need repacking, we set the stride to the values we just
5796 calculated, recalculate the offset and copy the array data.
5797 Code is also added to copy the data back at the end of the function.
5801 gfc_trans_dummy_array_bias (gfc_symbol
* sym
, tree tmpdesc
,
5802 gfc_wrapped_block
* block
)
5809 tree stmtInit
, stmtCleanup
;
5816 tree stride
, stride2
;
5826 /* Do nothing for pointer and allocatable arrays. */
5827 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
5830 if (sym
->attr
.dummy
&& gfc_is_nodesc_array (sym
))
5832 gfc_trans_g77_array (sym
, block
);
5836 gfc_save_backend_locus (&loc
);
5837 gfc_set_backend_locus (&sym
->declared_at
);
5839 /* Descriptor type. */
5840 type
= TREE_TYPE (tmpdesc
);
5841 gcc_assert (GFC_ARRAY_TYPE_P (type
));
5842 dumdesc
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
5843 dumdesc
= build_fold_indirect_ref_loc (input_location
, dumdesc
);
5844 gfc_start_block (&init
);
5846 if (sym
->ts
.type
== BT_CHARACTER
5847 && TREE_CODE (sym
->ts
.u
.cl
->backend_decl
) == VAR_DECL
)
5848 gfc_conv_string_length (sym
->ts
.u
.cl
, NULL
, &init
);
5850 checkparm
= (sym
->as
->type
== AS_EXPLICIT
5851 && (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
));
5853 no_repack
= !(GFC_DECL_PACKED_ARRAY (tmpdesc
)
5854 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc
));
5856 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc
))
5858 /* For non-constant shape arrays we only check if the first dimension
5859 is contiguous. Repacking higher dimensions wouldn't gain us
5860 anything as we still don't know the array stride. */
5861 partial
= gfc_create_var (boolean_type_node
, "partial");
5862 TREE_USED (partial
) = 1;
5863 tmp
= gfc_conv_descriptor_stride_get (dumdesc
, gfc_rank_cst
[0]);
5864 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, tmp
,
5865 gfc_index_one_node
);
5866 gfc_add_modify (&init
, partial
, tmp
);
5869 partial
= NULL_TREE
;
5871 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
5872 here, however I think it does the right thing. */
5875 /* Set the first stride. */
5876 stride
= gfc_conv_descriptor_stride_get (dumdesc
, gfc_rank_cst
[0]);
5877 stride
= gfc_evaluate_now (stride
, &init
);
5879 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
5880 stride
, gfc_index_zero_node
);
5881 tmp
= fold_build3_loc (input_location
, COND_EXPR
, gfc_array_index_type
,
5882 tmp
, gfc_index_one_node
, stride
);
5883 stride
= GFC_TYPE_ARRAY_STRIDE (type
, 0);
5884 gfc_add_modify (&init
, stride
, tmp
);
5886 /* Allow the user to disable array repacking. */
5887 stmt_unpacked
= NULL_TREE
;
5891 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type
, 0)));
5892 /* A library call to repack the array if necessary. */
5893 tmp
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
5894 stmt_unpacked
= build_call_expr_loc (input_location
,
5895 gfor_fndecl_in_pack
, 1, tmp
);
5897 stride
= gfc_index_one_node
;
5899 if (gfc_option
.warn_array_temp
)
5900 gfc_warning ("Creating array temporary at %L", &loc
);
5903 /* This is for the case where the array data is used directly without
5904 calling the repack function. */
5905 if (no_repack
|| partial
!= NULL_TREE
)
5906 stmt_packed
= gfc_conv_descriptor_data_get (dumdesc
);
5908 stmt_packed
= NULL_TREE
;
5910 /* Assign the data pointer. */
5911 if (stmt_packed
!= NULL_TREE
&& stmt_unpacked
!= NULL_TREE
)
5913 /* Don't repack unknown shape arrays when the first stride is 1. */
5914 tmp
= fold_build3_loc (input_location
, COND_EXPR
, TREE_TYPE (stmt_packed
),
5915 partial
, stmt_packed
, stmt_unpacked
);
5918 tmp
= stmt_packed
!= NULL_TREE
? stmt_packed
: stmt_unpacked
;
5919 gfc_add_modify (&init
, tmpdesc
, fold_convert (type
, tmp
));
5921 offset
= gfc_index_zero_node
;
5922 size
= gfc_index_one_node
;
5924 /* Evaluate the bounds of the array. */
5925 for (n
= 0; n
< sym
->as
->rank
; n
++)
5927 if (checkparm
|| !sym
->as
->upper
[n
])
5929 /* Get the bounds of the actual parameter. */
5930 dubound
= gfc_conv_descriptor_ubound_get (dumdesc
, gfc_rank_cst
[n
]);
5931 dlbound
= gfc_conv_descriptor_lbound_get (dumdesc
, gfc_rank_cst
[n
]);
5935 dubound
= NULL_TREE
;
5936 dlbound
= NULL_TREE
;
5939 lbound
= GFC_TYPE_ARRAY_LBOUND (type
, n
);
5940 if (!INTEGER_CST_P (lbound
))
5942 gfc_init_se (&se
, NULL
);
5943 gfc_conv_expr_type (&se
, sym
->as
->lower
[n
],
5944 gfc_array_index_type
);
5945 gfc_add_block_to_block (&init
, &se
.pre
);
5946 gfc_add_modify (&init
, lbound
, se
.expr
);
5949 ubound
= GFC_TYPE_ARRAY_UBOUND (type
, n
);
5950 /* Set the desired upper bound. */
5951 if (sym
->as
->upper
[n
])
5953 /* We know what we want the upper bound to be. */
5954 if (!INTEGER_CST_P (ubound
))
5956 gfc_init_se (&se
, NULL
);
5957 gfc_conv_expr_type (&se
, sym
->as
->upper
[n
],
5958 gfc_array_index_type
);
5959 gfc_add_block_to_block (&init
, &se
.pre
);
5960 gfc_add_modify (&init
, ubound
, se
.expr
);
5963 /* Check the sizes match. */
5966 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
5970 temp
= fold_build2_loc (input_location
, MINUS_EXPR
,
5971 gfc_array_index_type
, ubound
, lbound
);
5972 temp
= fold_build2_loc (input_location
, PLUS_EXPR
,
5973 gfc_array_index_type
,
5974 gfc_index_one_node
, temp
);
5975 stride2
= fold_build2_loc (input_location
, MINUS_EXPR
,
5976 gfc_array_index_type
, dubound
,
5978 stride2
= fold_build2_loc (input_location
, PLUS_EXPR
,
5979 gfc_array_index_type
,
5980 gfc_index_one_node
, stride2
);
5981 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
5982 gfc_array_index_type
, temp
, stride2
);
5983 asprintf (&msg
, "Dimension %d of array '%s' has extent "
5984 "%%ld instead of %%ld", n
+1, sym
->name
);
5986 gfc_trans_runtime_check (true, false, tmp
, &init
, &loc
, msg
,
5987 fold_convert (long_integer_type_node
, temp
),
5988 fold_convert (long_integer_type_node
, stride2
));
5995 /* For assumed shape arrays move the upper bound by the same amount
5996 as the lower bound. */
5997 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
5998 gfc_array_index_type
, dubound
, dlbound
);
5999 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
6000 gfc_array_index_type
, tmp
, lbound
);
6001 gfc_add_modify (&init
, ubound
, tmp
);
6003 /* The offset of this dimension. offset = offset - lbound * stride. */
6004 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
6006 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
6007 gfc_array_index_type
, offset
, tmp
);
6009 /* The size of this dimension, and the stride of the next. */
6010 if (n
+ 1 < sym
->as
->rank
)
6012 stride
= GFC_TYPE_ARRAY_STRIDE (type
, n
+ 1);
6014 if (no_repack
|| partial
!= NULL_TREE
)
6016 gfc_conv_descriptor_stride_get (dumdesc
, gfc_rank_cst
[n
+1]);
6018 /* Figure out the stride if not a known constant. */
6019 if (!INTEGER_CST_P (stride
))
6022 stmt_packed
= NULL_TREE
;
6025 /* Calculate stride = size * (ubound + 1 - lbound). */
6026 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6027 gfc_array_index_type
,
6028 gfc_index_one_node
, lbound
);
6029 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
6030 gfc_array_index_type
, ubound
, tmp
);
6031 size
= fold_build2_loc (input_location
, MULT_EXPR
,
6032 gfc_array_index_type
, size
, tmp
);
6036 /* Assign the stride. */
6037 if (stmt_packed
!= NULL_TREE
&& stmt_unpacked
!= NULL_TREE
)
6038 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
6039 gfc_array_index_type
, partial
,
6040 stmt_unpacked
, stmt_packed
);
6042 tmp
= (stmt_packed
!= NULL_TREE
) ? stmt_packed
: stmt_unpacked
;
6043 gfc_add_modify (&init
, stride
, tmp
);
6048 stride
= GFC_TYPE_ARRAY_SIZE (type
);
6050 if (stride
&& !INTEGER_CST_P (stride
))
6052 /* Calculate size = stride * (ubound + 1 - lbound). */
6053 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6054 gfc_array_index_type
,
6055 gfc_index_one_node
, lbound
);
6056 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
6057 gfc_array_index_type
,
6059 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
6060 gfc_array_index_type
,
6061 GFC_TYPE_ARRAY_STRIDE (type
, n
), tmp
);
6062 gfc_add_modify (&init
, stride
, tmp
);
6067 gfc_trans_array_cobounds (type
, &init
, sym
);
6069 /* Set the offset. */
6070 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
6071 gfc_add_modify (&init
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
6073 gfc_trans_vla_type_sizes (sym
, &init
);
6075 stmtInit
= gfc_finish_block (&init
);
6077 /* Only do the entry/initialization code if the arg is present. */
6078 dumdesc
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
6079 optional_arg
= (sym
->attr
.optional
6080 || (sym
->ns
->proc_name
->attr
.entry_master
6081 && sym
->attr
.dummy
));
6084 tmp
= gfc_conv_expr_present (sym
);
6085 stmtInit
= build3_v (COND_EXPR
, tmp
, stmtInit
,
6086 build_empty_stmt (input_location
));
6091 stmtCleanup
= NULL_TREE
;
6094 stmtblock_t cleanup
;
6095 gfc_start_block (&cleanup
);
6097 if (sym
->attr
.intent
!= INTENT_IN
)
6099 /* Copy the data back. */
6100 tmp
= build_call_expr_loc (input_location
,
6101 gfor_fndecl_in_unpack
, 2, dumdesc
, tmpdesc
);
6102 gfc_add_expr_to_block (&cleanup
, tmp
);
6105 /* Free the temporary. */
6106 tmp
= gfc_call_free (tmpdesc
);
6107 gfc_add_expr_to_block (&cleanup
, tmp
);
6109 stmtCleanup
= gfc_finish_block (&cleanup
);
6111 /* Only do the cleanup if the array was repacked. */
6112 tmp
= build_fold_indirect_ref_loc (input_location
, dumdesc
);
6113 tmp
= gfc_conv_descriptor_data_get (tmp
);
6114 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
6116 stmtCleanup
= build3_v (COND_EXPR
, tmp
, stmtCleanup
,
6117 build_empty_stmt (input_location
));
6121 tmp
= gfc_conv_expr_present (sym
);
6122 stmtCleanup
= build3_v (COND_EXPR
, tmp
, stmtCleanup
,
6123 build_empty_stmt (input_location
));
6127 /* We don't need to free any memory allocated by internal_pack as it will
6128 be freed at the end of the function by pop_context. */
6129 gfc_add_init_cleanup (block
, stmtInit
, stmtCleanup
);
6131 gfc_restore_backend_locus (&loc
);
6135 /* Calculate the overall offset, including subreferences. */
6137 gfc_get_dataptr_offset (stmtblock_t
*block
, tree parm
, tree desc
, tree offset
,
6138 bool subref
, gfc_expr
*expr
)
6148 /* If offset is NULL and this is not a subreferenced array, there is
6150 if (offset
== NULL_TREE
)
6153 offset
= gfc_index_zero_node
;
6158 tmp
= build_array_ref (desc
, offset
, NULL
);
6160 /* Offset the data pointer for pointer assignments from arrays with
6161 subreferences; e.g. my_integer => my_type(:)%integer_component. */
6164 /* Go past the array reference. */
6165 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
6166 if (ref
->type
== REF_ARRAY
&&
6167 ref
->u
.ar
.type
!= AR_ELEMENT
)
6173 /* Calculate the offset for each subsequent subreference. */
6174 for (; ref
; ref
= ref
->next
)
6179 field
= ref
->u
.c
.component
->backend_decl
;
6180 gcc_assert (field
&& TREE_CODE (field
) == FIELD_DECL
);
6181 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
,
6183 tmp
, field
, NULL_TREE
);
6187 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
);
6188 gfc_init_se (&start
, NULL
);
6189 gfc_conv_expr_type (&start
, ref
->u
.ss
.start
, gfc_charlen_type_node
);
6190 gfc_add_block_to_block (block
, &start
.pre
);
6191 tmp
= gfc_build_array_ref (tmp
, start
.expr
, NULL
);
6195 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
6196 && ref
->u
.ar
.type
== AR_ELEMENT
);
6198 /* TODO - Add bounds checking. */
6199 stride
= gfc_index_one_node
;
6200 index
= gfc_index_zero_node
;
6201 for (n
= 0; n
< ref
->u
.ar
.dimen
; n
++)
6206 /* Update the index. */
6207 gfc_init_se (&start
, NULL
);
6208 gfc_conv_expr_type (&start
, ref
->u
.ar
.start
[n
], gfc_array_index_type
);
6209 itmp
= gfc_evaluate_now (start
.expr
, block
);
6210 gfc_init_se (&start
, NULL
);
6211 gfc_conv_expr_type (&start
, ref
->u
.ar
.as
->lower
[n
], gfc_array_index_type
);
6212 jtmp
= gfc_evaluate_now (start
.expr
, block
);
6213 itmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6214 gfc_array_index_type
, itmp
, jtmp
);
6215 itmp
= fold_build2_loc (input_location
, MULT_EXPR
,
6216 gfc_array_index_type
, itmp
, stride
);
6217 index
= fold_build2_loc (input_location
, PLUS_EXPR
,
6218 gfc_array_index_type
, itmp
, index
);
6219 index
= gfc_evaluate_now (index
, block
);
6221 /* Update the stride. */
6222 gfc_init_se (&start
, NULL
);
6223 gfc_conv_expr_type (&start
, ref
->u
.ar
.as
->upper
[n
], gfc_array_index_type
);
6224 itmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6225 gfc_array_index_type
, start
.expr
,
6227 itmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
6228 gfc_array_index_type
,
6229 gfc_index_one_node
, itmp
);
6230 stride
= fold_build2_loc (input_location
, MULT_EXPR
,
6231 gfc_array_index_type
, stride
, itmp
);
6232 stride
= gfc_evaluate_now (stride
, block
);
6235 /* Apply the index to obtain the array element. */
6236 tmp
= gfc_build_array_ref (tmp
, index
, NULL
);
6246 /* Set the target data pointer. */
6247 offset
= gfc_build_addr_expr (gfc_array_dataptr_type (desc
), tmp
);
6248 gfc_conv_descriptor_data_set (block
, parm
, offset
);
6252 /* gfc_conv_expr_descriptor needs the string length an expression
6253 so that the size of the temporary can be obtained. This is done
6254 by adding up the string lengths of all the elements in the
6255 expression. Function with non-constant expressions have their
6256 string lengths mapped onto the actual arguments using the
6257 interface mapping machinery in trans-expr.c. */
6259 get_array_charlen (gfc_expr
*expr
, gfc_se
*se
)
6261 gfc_interface_mapping mapping
;
6262 gfc_formal_arglist
*formal
;
6263 gfc_actual_arglist
*arg
;
6266 if (expr
->ts
.u
.cl
->length
6267 && gfc_is_constant_expr (expr
->ts
.u
.cl
->length
))
6269 if (!expr
->ts
.u
.cl
->backend_decl
)
6270 gfc_conv_string_length (expr
->ts
.u
.cl
, expr
, &se
->pre
);
6274 switch (expr
->expr_type
)
6277 get_array_charlen (expr
->value
.op
.op1
, se
);
6279 /* For parentheses the expression ts.u.cl is identical. */
6280 if (expr
->value
.op
.op
== INTRINSIC_PARENTHESES
)
6283 expr
->ts
.u
.cl
->backend_decl
=
6284 gfc_create_var (gfc_charlen_type_node
, "sln");
6286 if (expr
->value
.op
.op2
)
6288 get_array_charlen (expr
->value
.op
.op2
, se
);
6290 gcc_assert (expr
->value
.op
.op
== INTRINSIC_CONCAT
);
6292 /* Add the string lengths and assign them to the expression
6293 string length backend declaration. */
6294 gfc_add_modify (&se
->pre
, expr
->ts
.u
.cl
->backend_decl
,
6295 fold_build2_loc (input_location
, PLUS_EXPR
,
6296 gfc_charlen_type_node
,
6297 expr
->value
.op
.op1
->ts
.u
.cl
->backend_decl
,
6298 expr
->value
.op
.op2
->ts
.u
.cl
->backend_decl
));
6301 gfc_add_modify (&se
->pre
, expr
->ts
.u
.cl
->backend_decl
,
6302 expr
->value
.op
.op1
->ts
.u
.cl
->backend_decl
);
6306 if (expr
->value
.function
.esym
== NULL
6307 || expr
->ts
.u
.cl
->length
->expr_type
== EXPR_CONSTANT
)
6309 gfc_conv_string_length (expr
->ts
.u
.cl
, expr
, &se
->pre
);
6313 /* Map expressions involving the dummy arguments onto the actual
6314 argument expressions. */
6315 gfc_init_interface_mapping (&mapping
);
6316 formal
= gfc_sym_get_dummy_args (expr
->symtree
->n
.sym
);
6317 arg
= expr
->value
.function
.actual
;
6319 /* Set se = NULL in the calls to the interface mapping, to suppress any
6321 for (; arg
!= NULL
; arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
)
6326 gfc_add_interface_mapping (&mapping
, formal
->sym
, NULL
, arg
->expr
);
6329 gfc_init_se (&tse
, NULL
);
6331 /* Build the expression for the character length and convert it. */
6332 gfc_apply_interface_mapping (&mapping
, &tse
, expr
->ts
.u
.cl
->length
);
6334 gfc_add_block_to_block (&se
->pre
, &tse
.pre
);
6335 gfc_add_block_to_block (&se
->post
, &tse
.post
);
6336 tse
.expr
= fold_convert (gfc_charlen_type_node
, tse
.expr
);
6337 tse
.expr
= fold_build2_loc (input_location
, MAX_EXPR
,
6338 gfc_charlen_type_node
, tse
.expr
,
6339 build_int_cst (gfc_charlen_type_node
, 0));
6340 expr
->ts
.u
.cl
->backend_decl
= tse
.expr
;
6341 gfc_free_interface_mapping (&mapping
);
6345 gfc_conv_string_length (expr
->ts
.u
.cl
, expr
, &se
->pre
);
6351 /* Helper function to check dimensions. */
6353 transposed_dims (gfc_ss
*ss
)
6357 for (n
= 0; n
< ss
->dimen
; n
++)
6358 if (ss
->dim
[n
] != n
)
6364 /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an
6365 AR_FULL, suitable for the scalarizer. */
6368 walk_coarray (gfc_expr
*e
)
6372 gcc_assert (gfc_get_corank (e
) > 0);
6374 ss
= gfc_walk_expr (e
);
6376 /* Fix scalar coarray. */
6377 if (ss
== gfc_ss_terminator
)
6384 if (ref
->type
== REF_ARRAY
6385 && ref
->u
.ar
.codimen
> 0)
6391 gcc_assert (ref
!= NULL
);
6392 if (ref
->u
.ar
.type
== AR_ELEMENT
)
6393 ref
->u
.ar
.type
= AR_SECTION
;
6394 ss
= gfc_reverse_ss (gfc_walk_array_ref (ss
, e
, ref
));
6401 /* Convert an array for passing as an actual argument. Expressions and
6402 vector subscripts are evaluated and stored in a temporary, which is then
6403 passed. For whole arrays the descriptor is passed. For array sections
6404 a modified copy of the descriptor is passed, but using the original data.
6406 This function is also used for array pointer assignments, and there
6409 - se->want_pointer && !se->direct_byref
6410 EXPR is an actual argument. On exit, se->expr contains a
6411 pointer to the array descriptor.
6413 - !se->want_pointer && !se->direct_byref
6414 EXPR is an actual argument to an intrinsic function or the
6415 left-hand side of a pointer assignment. On exit, se->expr
6416 contains the descriptor for EXPR.
6418 - !se->want_pointer && se->direct_byref
6419 EXPR is the right-hand side of a pointer assignment and
6420 se->expr is the descriptor for the previously-evaluated
6421 left-hand side. The function creates an assignment from
6425 The se->force_tmp flag disables the non-copying descriptor optimization
6426 that is used for transpose. It may be used in cases where there is an
6427 alias between the transpose argument and another argument in the same
6431 gfc_conv_expr_descriptor (gfc_se
*se
, gfc_expr
*expr
)
6434 gfc_ss_type ss_type
;
6435 gfc_ss_info
*ss_info
;
6437 gfc_array_info
*info
;
6446 bool subref_array_target
= false;
6447 gfc_expr
*arg
, *ss_expr
;
6449 if (se
->want_coarray
)
6450 ss
= walk_coarray (expr
);
6452 ss
= gfc_walk_expr (expr
);
6454 gcc_assert (ss
!= NULL
);
6455 gcc_assert (ss
!= gfc_ss_terminator
);
6458 ss_type
= ss_info
->type
;
6459 ss_expr
= ss_info
->expr
;
6461 /* Special case: TRANSPOSE which needs no temporary. */
6462 while (expr
->expr_type
== EXPR_FUNCTION
&& expr
->value
.function
.isym
6463 && NULL
!= (arg
= gfc_get_noncopying_intrinsic_argument (expr
)))
6465 /* This is a call to transpose which has already been handled by the
6466 scalarizer, so that we just need to get its argument's descriptor. */
6467 gcc_assert (expr
->value
.function
.isym
->id
== GFC_ISYM_TRANSPOSE
);
6468 expr
= expr
->value
.function
.actual
->expr
;
6471 /* Special case things we know we can pass easily. */
6472 switch (expr
->expr_type
)
6475 /* If we have a linear array section, we can pass it directly.
6476 Otherwise we need to copy it into a temporary. */
6478 gcc_assert (ss_type
== GFC_SS_SECTION
);
6479 gcc_assert (ss_expr
== expr
);
6480 info
= &ss_info
->data
.array
;
6482 /* Get the descriptor for the array. */
6483 gfc_conv_ss_descriptor (&se
->pre
, ss
, 0);
6484 desc
= info
->descriptor
;
6486 subref_array_target
= se
->direct_byref
&& is_subref_array (expr
);
6487 need_tmp
= gfc_ref_needs_temporary_p (expr
->ref
)
6488 && !subref_array_target
;
6495 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
6497 /* Create a new descriptor if the array doesn't have one. */
6500 else if (info
->ref
->u
.ar
.type
== AR_FULL
|| se
->descriptor_only
)
6502 else if (se
->direct_byref
)
6505 full
= gfc_full_array_ref_p (info
->ref
, NULL
);
6507 if (full
&& !transposed_dims (ss
))
6509 if (se
->direct_byref
&& !se
->byref_noassign
)
6511 /* Copy the descriptor for pointer assignments. */
6512 gfc_add_modify (&se
->pre
, se
->expr
, desc
);
6514 /* Add any offsets from subreferences. */
6515 gfc_get_dataptr_offset (&se
->pre
, se
->expr
, desc
, NULL_TREE
,
6516 subref_array_target
, expr
);
6518 else if (se
->want_pointer
)
6520 /* We pass full arrays directly. This means that pointers and
6521 allocatable arrays should also work. */
6522 se
->expr
= gfc_build_addr_expr (NULL_TREE
, desc
);
6529 if (expr
->ts
.type
== BT_CHARACTER
)
6530 se
->string_length
= gfc_get_expr_charlen (expr
);
6532 gfc_free_ss_chain (ss
);
6538 /* A transformational function return value will be a temporary
6539 array descriptor. We still need to go through the scalarizer
6540 to create the descriptor. Elemental functions are handled as
6541 arbitrary expressions, i.e. copy to a temporary. */
6543 if (se
->direct_byref
)
6545 gcc_assert (ss_type
== GFC_SS_FUNCTION
&& ss_expr
== expr
);
6547 /* For pointer assignments pass the descriptor directly. */
6551 gcc_assert (se
->ss
== ss
);
6552 se
->expr
= gfc_build_addr_expr (NULL_TREE
, se
->expr
);
6553 gfc_conv_expr (se
, expr
);
6554 gfc_free_ss_chain (ss
);
6558 if (ss_expr
!= expr
|| ss_type
!= GFC_SS_FUNCTION
)
6560 if (ss_expr
!= expr
)
6561 /* Elemental function. */
6562 gcc_assert ((expr
->value
.function
.esym
!= NULL
6563 && expr
->value
.function
.esym
->attr
.elemental
)
6564 || (expr
->value
.function
.isym
!= NULL
6565 && expr
->value
.function
.isym
->elemental
)
6566 || gfc_inline_intrinsic_function_p (expr
));
6568 gcc_assert (ss_type
== GFC_SS_INTRINSIC
);
6571 if (expr
->ts
.type
== BT_CHARACTER
6572 && expr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6573 get_array_charlen (expr
, se
);
6579 /* Transformational function. */
6580 info
= &ss_info
->data
.array
;
6586 /* Constant array constructors don't need a temporary. */
6587 if (ss_type
== GFC_SS_CONSTRUCTOR
6588 && expr
->ts
.type
!= BT_CHARACTER
6589 && gfc_constant_array_constructor_p (expr
->value
.constructor
))
6592 info
= &ss_info
->data
.array
;
6602 /* Something complicated. Copy it into a temporary. */
6608 /* If we are creating a temporary, we don't need to bother about aliases
6613 gfc_init_loopinfo (&loop
);
6615 /* Associate the SS with the loop. */
6616 gfc_add_ss_to_loop (&loop
, ss
);
6618 /* Tell the scalarizer not to bother creating loop variables, etc. */
6620 loop
.array_parameter
= 1;
6622 /* The right-hand side of a pointer assignment mustn't use a temporary. */
6623 gcc_assert (!se
->direct_byref
);
6625 /* Setup the scalarizing loops and bounds. */
6626 gfc_conv_ss_startstride (&loop
);
6630 if (expr
->ts
.type
== BT_CHARACTER
&& !expr
->ts
.u
.cl
->backend_decl
)
6631 get_array_charlen (expr
, se
);
6633 /* Tell the scalarizer to make a temporary. */
6634 loop
.temp_ss
= gfc_get_temp_ss (gfc_typenode_for_spec (&expr
->ts
),
6635 ((expr
->ts
.type
== BT_CHARACTER
)
6636 ? expr
->ts
.u
.cl
->backend_decl
6640 se
->string_length
= loop
.temp_ss
->info
->string_length
;
6641 gcc_assert (loop
.temp_ss
->dimen
== loop
.dimen
);
6642 gfc_add_ss_to_loop (&loop
, loop
.temp_ss
);
6645 gfc_conv_loop_setup (&loop
, & expr
->where
);
6649 /* Copy into a temporary and pass that. We don't need to copy the data
6650 back because expressions and vector subscripts must be INTENT_IN. */
6651 /* TODO: Optimize passing function return values. */
6655 /* Start the copying loops. */
6656 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
6657 gfc_mark_ss_chain_used (ss
, 1);
6658 gfc_start_scalarized_body (&loop
, &block
);
6660 /* Copy each data element. */
6661 gfc_init_se (&lse
, NULL
);
6662 gfc_copy_loopinfo_to_se (&lse
, &loop
);
6663 gfc_init_se (&rse
, NULL
);
6664 gfc_copy_loopinfo_to_se (&rse
, &loop
);
6666 lse
.ss
= loop
.temp_ss
;
6669 gfc_conv_scalarized_array_ref (&lse
, NULL
);
6670 if (expr
->ts
.type
== BT_CHARACTER
)
6672 gfc_conv_expr (&rse
, expr
);
6673 if (POINTER_TYPE_P (TREE_TYPE (rse
.expr
)))
6674 rse
.expr
= build_fold_indirect_ref_loc (input_location
,
6678 gfc_conv_expr_val (&rse
, expr
);
6680 gfc_add_block_to_block (&block
, &rse
.pre
);
6681 gfc_add_block_to_block (&block
, &lse
.pre
);
6683 lse
.string_length
= rse
.string_length
;
6684 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, true,
6685 expr
->expr_type
== EXPR_VARIABLE
6686 || expr
->expr_type
== EXPR_ARRAY
, true);
6687 gfc_add_expr_to_block (&block
, tmp
);
6689 /* Finish the copying loops. */
6690 gfc_trans_scalarizing_loops (&loop
, &block
);
6692 desc
= loop
.temp_ss
->info
->data
.array
.descriptor
;
6694 else if (expr
->expr_type
== EXPR_FUNCTION
&& !transposed_dims (ss
))
6696 desc
= info
->descriptor
;
6697 se
->string_length
= ss_info
->string_length
;
6701 /* We pass sections without copying to a temporary. Make a new
6702 descriptor and point it at the section we want. The loop variable
6703 limits will be the limits of the section.
6704 A function may decide to repack the array to speed up access, but
6705 we're not bothered about that here. */
6706 int dim
, ndim
, codim
;
6714 ndim
= info
->ref
? info
->ref
->u
.ar
.dimen
: ss
->dimen
;
6716 if (se
->want_coarray
)
6718 gfc_array_ref
*ar
= &info
->ref
->u
.ar
;
6720 codim
= gfc_get_corank (expr
);
6721 for (n
= 0; n
< codim
- 1; n
++)
6723 /* Make sure we are not lost somehow. */
6724 gcc_assert (ar
->dimen_type
[n
+ ndim
] == DIMEN_THIS_IMAGE
);
6726 /* Make sure the call to gfc_conv_section_startstride won't
6727 generate unnecessary code to calculate stride. */
6728 gcc_assert (ar
->stride
[n
+ ndim
] == NULL
);
6730 gfc_conv_section_startstride (&loop
, ss
, n
+ ndim
);
6731 loop
.from
[n
+ loop
.dimen
] = info
->start
[n
+ ndim
];
6732 loop
.to
[n
+ loop
.dimen
] = info
->end
[n
+ ndim
];
6735 gcc_assert (n
== codim
- 1);
6736 evaluate_bound (&loop
.pre
, info
->start
, ar
->start
,
6737 info
->descriptor
, n
+ ndim
, true);
6738 loop
.from
[n
+ loop
.dimen
] = info
->start
[n
+ ndim
];
6743 /* Set the string_length for a character array. */
6744 if (expr
->ts
.type
== BT_CHARACTER
)
6745 se
->string_length
= gfc_get_expr_charlen (expr
);
6747 desc
= info
->descriptor
;
6748 if (se
->direct_byref
&& !se
->byref_noassign
)
6750 /* For pointer assignments we fill in the destination. */
6752 parmtype
= TREE_TYPE (parm
);
6756 /* Otherwise make a new one. */
6757 parmtype
= gfc_get_element_type (TREE_TYPE (desc
));
6758 parmtype
= gfc_get_array_type_bounds (parmtype
, loop
.dimen
, codim
,
6759 loop
.from
, loop
.to
, 0,
6760 GFC_ARRAY_UNKNOWN
, false);
6761 parm
= gfc_create_var (parmtype
, "parm");
6764 offset
= gfc_index_zero_node
;
6766 /* The following can be somewhat confusing. We have two
6767 descriptors, a new one and the original array.
6768 {parm, parmtype, dim} refer to the new one.
6769 {desc, type, n, loop} refer to the original, which maybe
6770 a descriptorless array.
6771 The bounds of the scalarization are the bounds of the section.
6772 We don't have to worry about numeric overflows when calculating
6773 the offsets because all elements are within the array data. */
6775 /* Set the dtype. */
6776 tmp
= gfc_conv_descriptor_dtype (parm
);
6777 gfc_add_modify (&loop
.pre
, tmp
, gfc_get_dtype (parmtype
));
6779 /* Set offset for assignments to pointer only to zero if it is not
6781 if (se
->direct_byref
6782 && info
->ref
&& info
->ref
->u
.ar
.type
!= AR_FULL
)
6783 base
= gfc_index_zero_node
;
6784 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
6785 base
= gfc_evaluate_now (gfc_conv_array_offset (desc
), &loop
.pre
);
6789 for (n
= 0; n
< ndim
; n
++)
6791 stride
= gfc_conv_array_stride (desc
, n
);
6793 /* Work out the offset. */
6795 && info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_ELEMENT
)
6797 gcc_assert (info
->subscript
[n
]
6798 && info
->subscript
[n
]->info
->type
== GFC_SS_SCALAR
);
6799 start
= info
->subscript
[n
]->info
->data
.scalar
.value
;
6803 /* Evaluate and remember the start of the section. */
6804 start
= info
->start
[n
];
6805 stride
= gfc_evaluate_now (stride
, &loop
.pre
);
6808 tmp
= gfc_conv_array_lbound (desc
, n
);
6809 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (tmp
),
6811 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (tmp
),
6813 offset
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (tmp
),
6817 && info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_ELEMENT
)
6819 /* For elemental dimensions, we only need the offset. */
6823 /* Vector subscripts need copying and are handled elsewhere. */
6825 gcc_assert (info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_RANGE
);
6827 /* look for the corresponding scalarizer dimension: dim. */
6828 for (dim
= 0; dim
< ndim
; dim
++)
6829 if (ss
->dim
[dim
] == n
)
6832 /* loop exited early: the DIM being looked for has been found. */
6833 gcc_assert (dim
< ndim
);
6835 /* Set the new lower bound. */
6836 from
= loop
.from
[dim
];
6839 /* If we have an array section or are assigning make sure that
6840 the lower bound is 1. References to the full
6841 array should otherwise keep the original bounds. */
6843 || info
->ref
->u
.ar
.type
!= AR_FULL
)
6844 && !integer_onep (from
))
6846 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6847 gfc_array_index_type
, gfc_index_one_node
,
6849 to
= fold_build2_loc (input_location
, PLUS_EXPR
,
6850 gfc_array_index_type
, to
, tmp
);
6851 from
= gfc_index_one_node
;
6853 gfc_conv_descriptor_lbound_set (&loop
.pre
, parm
,
6854 gfc_rank_cst
[dim
], from
);
6856 /* Set the new upper bound. */
6857 gfc_conv_descriptor_ubound_set (&loop
.pre
, parm
,
6858 gfc_rank_cst
[dim
], to
);
6860 /* Multiply the stride by the section stride to get the
6862 stride
= fold_build2_loc (input_location
, MULT_EXPR
,
6863 gfc_array_index_type
,
6864 stride
, info
->stride
[n
]);
6866 if (se
->direct_byref
6868 && info
->ref
->u
.ar
.type
!= AR_FULL
)
6870 base
= fold_build2_loc (input_location
, MINUS_EXPR
,
6871 TREE_TYPE (base
), base
, stride
);
6873 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
6875 tmp
= gfc_conv_array_lbound (desc
, n
);
6876 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
6877 TREE_TYPE (base
), tmp
, loop
.from
[dim
]);
6878 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
6879 TREE_TYPE (base
), tmp
,
6880 gfc_conv_array_stride (desc
, n
));
6881 base
= fold_build2_loc (input_location
, PLUS_EXPR
,
6882 TREE_TYPE (base
), tmp
, base
);
6885 /* Store the new stride. */
6886 gfc_conv_descriptor_stride_set (&loop
.pre
, parm
,
6887 gfc_rank_cst
[dim
], stride
);
6890 for (n
= loop
.dimen
; n
< loop
.dimen
+ codim
; n
++)
6892 from
= loop
.from
[n
];
6894 gfc_conv_descriptor_lbound_set (&loop
.pre
, parm
,
6895 gfc_rank_cst
[n
], from
);
6896 if (n
< loop
.dimen
+ codim
- 1)
6897 gfc_conv_descriptor_ubound_set (&loop
.pre
, parm
,
6898 gfc_rank_cst
[n
], to
);
6901 if (se
->data_not_needed
)
6902 gfc_conv_descriptor_data_set (&loop
.pre
, parm
,
6903 gfc_index_zero_node
);
6905 /* Point the data pointer at the 1st element in the section. */
6906 gfc_get_dataptr_offset (&loop
.pre
, parm
, desc
, offset
,
6907 subref_array_target
, expr
);
6909 if ((se
->direct_byref
|| GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
6910 && !se
->data_not_needed
)
6912 /* Set the offset. */
6913 gfc_conv_descriptor_offset_set (&loop
.pre
, parm
, base
);
6917 /* Only the callee knows what the correct offset it, so just set
6919 gfc_conv_descriptor_offset_set (&loop
.pre
, parm
, gfc_index_zero_node
);
6924 if (!se
->direct_byref
|| se
->byref_noassign
)
6926 /* Get a pointer to the new descriptor. */
6927 if (se
->want_pointer
)
6928 se
->expr
= gfc_build_addr_expr (NULL_TREE
, desc
);
6933 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
6934 gfc_add_block_to_block (&se
->post
, &loop
.post
);
6936 /* Cleanup the scalarizer. */
6937 gfc_cleanup_loop (&loop
);
6940 /* Helper function for gfc_conv_array_parameter if array size needs to be
6944 array_parameter_size (tree desc
, gfc_expr
*expr
, tree
*size
)
6947 if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
6948 *size
= GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc
));
6949 else if (expr
->rank
> 1)
6950 *size
= build_call_expr_loc (input_location
,
6951 gfor_fndecl_size0
, 1,
6952 gfc_build_addr_expr (NULL
, desc
));
6955 tree ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_index_zero_node
);
6956 tree lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_index_zero_node
);
6958 *size
= fold_build2_loc (input_location
, MINUS_EXPR
,
6959 gfc_array_index_type
, ubound
, lbound
);
6960 *size
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
6961 *size
, gfc_index_one_node
);
6962 *size
= fold_build2_loc (input_location
, MAX_EXPR
, gfc_array_index_type
,
6963 *size
, gfc_index_zero_node
);
6965 elem
= TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc
)));
6966 *size
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
6967 *size
, fold_convert (gfc_array_index_type
, elem
));
6970 /* Convert an array for passing as an actual parameter. */
6971 /* TODO: Optimize passing g77 arrays. */
6974 gfc_conv_array_parameter (gfc_se
* se
, gfc_expr
* expr
, bool g77
,
6975 const gfc_symbol
*fsym
, const char *proc_name
,
6980 tree tmp
= NULL_TREE
;
6982 tree parent
= DECL_CONTEXT (current_function_decl
);
6983 bool full_array_var
;
6984 bool this_array_result
;
6987 bool array_constructor
;
6988 bool good_allocatable
;
6989 bool ultimate_ptr_comp
;
6990 bool ultimate_alloc_comp
;
6995 ultimate_ptr_comp
= false;
6996 ultimate_alloc_comp
= false;
6998 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
7000 if (ref
->next
== NULL
)
7003 if (ref
->type
== REF_COMPONENT
)
7005 ultimate_ptr_comp
= ref
->u
.c
.component
->attr
.pointer
;
7006 ultimate_alloc_comp
= ref
->u
.c
.component
->attr
.allocatable
;
7010 full_array_var
= false;
7013 if (expr
->expr_type
== EXPR_VARIABLE
&& ref
&& !ultimate_ptr_comp
)
7014 full_array_var
= gfc_full_array_ref_p (ref
, &contiguous
);
7016 sym
= full_array_var
? expr
->symtree
->n
.sym
: NULL
;
7018 /* The symbol should have an array specification. */
7019 gcc_assert (!sym
|| sym
->as
|| ref
->u
.ar
.as
);
7021 if (expr
->expr_type
== EXPR_ARRAY
&& expr
->ts
.type
== BT_CHARACTER
)
7023 get_array_ctor_strlen (&se
->pre
, expr
->value
.constructor
, &tmp
);
7024 expr
->ts
.u
.cl
->backend_decl
= tmp
;
7025 se
->string_length
= tmp
;
7028 /* Is this the result of the enclosing procedure? */
7029 this_array_result
= (full_array_var
&& sym
->attr
.flavor
== FL_PROCEDURE
);
7030 if (this_array_result
7031 && (sym
->backend_decl
!= current_function_decl
)
7032 && (sym
->backend_decl
!= parent
))
7033 this_array_result
= false;
7035 /* Passing address of the array if it is not pointer or assumed-shape. */
7036 if (full_array_var
&& g77
&& !this_array_result
7037 && sym
->ts
.type
!= BT_DERIVED
&& sym
->ts
.type
!= BT_CLASS
)
7039 tmp
= gfc_get_symbol_decl (sym
);
7041 if (sym
->ts
.type
== BT_CHARACTER
)
7042 se
->string_length
= sym
->ts
.u
.cl
->backend_decl
;
7044 if (!sym
->attr
.pointer
7046 && sym
->as
->type
!= AS_ASSUMED_SHAPE
7047 && sym
->as
->type
!= AS_DEFERRED
7048 && sym
->as
->type
!= AS_ASSUMED_RANK
7049 && !sym
->attr
.allocatable
)
7051 /* Some variables are declared directly, others are declared as
7052 pointers and allocated on the heap. */
7053 if (sym
->attr
.dummy
|| POINTER_TYPE_P (TREE_TYPE (tmp
)))
7056 se
->expr
= gfc_build_addr_expr (NULL_TREE
, tmp
);
7058 array_parameter_size (tmp
, expr
, size
);
7062 if (sym
->attr
.allocatable
)
7064 if (sym
->attr
.dummy
|| sym
->attr
.result
)
7066 gfc_conv_expr_descriptor (se
, expr
);
7070 array_parameter_size (tmp
, expr
, size
);
7071 se
->expr
= gfc_conv_array_data (tmp
);
7076 /* A convenient reduction in scope. */
7077 contiguous
= g77
&& !this_array_result
&& contiguous
;
7079 /* There is no need to pack and unpack the array, if it is contiguous
7080 and not a deferred- or assumed-shape array, or if it is simply
7082 no_pack
= ((sym
&& sym
->as
7083 && !sym
->attr
.pointer
7084 && sym
->as
->type
!= AS_DEFERRED
7085 && sym
->as
->type
!= AS_ASSUMED_RANK
7086 && sym
->as
->type
!= AS_ASSUMED_SHAPE
)
7088 (ref
&& ref
->u
.ar
.as
7089 && ref
->u
.ar
.as
->type
!= AS_DEFERRED
7090 && ref
->u
.ar
.as
->type
!= AS_ASSUMED_RANK
7091 && ref
->u
.ar
.as
->type
!= AS_ASSUMED_SHAPE
)
7093 gfc_is_simply_contiguous (expr
, false));
7095 no_pack
= contiguous
&& no_pack
;
7097 /* Array constructors are always contiguous and do not need packing. */
7098 array_constructor
= g77
&& !this_array_result
&& expr
->expr_type
== EXPR_ARRAY
;
7100 /* Same is true of contiguous sections from allocatable variables. */
7101 good_allocatable
= contiguous
7103 && expr
->symtree
->n
.sym
->attr
.allocatable
;
7105 /* Or ultimate allocatable components. */
7106 ultimate_alloc_comp
= contiguous
&& ultimate_alloc_comp
;
7108 if (no_pack
|| array_constructor
|| good_allocatable
|| ultimate_alloc_comp
)
7110 gfc_conv_expr_descriptor (se
, expr
);
7111 if (expr
->ts
.type
== BT_CHARACTER
)
7112 se
->string_length
= expr
->ts
.u
.cl
->backend_decl
;
7114 array_parameter_size (se
->expr
, expr
, size
);
7115 se
->expr
= gfc_conv_array_data (se
->expr
);
7119 if (this_array_result
)
7121 /* Result of the enclosing function. */
7122 gfc_conv_expr_descriptor (se
, expr
);
7124 array_parameter_size (se
->expr
, expr
, size
);
7125 se
->expr
= gfc_build_addr_expr (NULL_TREE
, se
->expr
);
7127 if (g77
&& TREE_TYPE (TREE_TYPE (se
->expr
)) != NULL_TREE
7128 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se
->expr
))))
7129 se
->expr
= gfc_conv_array_data (build_fold_indirect_ref_loc (input_location
,
7136 /* Every other type of array. */
7137 se
->want_pointer
= 1;
7138 gfc_conv_expr_descriptor (se
, expr
);
7140 array_parameter_size (build_fold_indirect_ref_loc (input_location
,
7145 /* Deallocate the allocatable components of structures that are
7147 if ((expr
->ts
.type
== BT_DERIVED
|| expr
->ts
.type
== BT_CLASS
)
7148 && expr
->ts
.u
.derived
->attr
.alloc_comp
7149 && expr
->expr_type
!= EXPR_VARIABLE
)
7151 tmp
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
7152 tmp
= gfc_deallocate_alloc_comp (expr
->ts
.u
.derived
, tmp
, expr
->rank
);
7154 /* The components shall be deallocated before their containing entity. */
7155 gfc_prepend_expr_to_block (&se
->post
, tmp
);
7158 if (g77
|| (fsym
&& fsym
->attr
.contiguous
7159 && !gfc_is_simply_contiguous (expr
, false)))
7161 tree origptr
= NULL_TREE
;
7165 /* For contiguous arrays, save the original value of the descriptor. */
7168 origptr
= gfc_create_var (pvoid_type_node
, "origptr");
7169 tmp
= build_fold_indirect_ref_loc (input_location
, desc
);
7170 tmp
= gfc_conv_array_data (tmp
);
7171 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
7172 TREE_TYPE (origptr
), origptr
,
7173 fold_convert (TREE_TYPE (origptr
), tmp
));
7174 gfc_add_expr_to_block (&se
->pre
, tmp
);
7177 /* Repack the array. */
7178 if (gfc_option
.warn_array_temp
)
7181 gfc_warning ("Creating array temporary at %L for argument '%s'",
7182 &expr
->where
, fsym
->name
);
7184 gfc_warning ("Creating array temporary at %L", &expr
->where
);
7187 ptr
= build_call_expr_loc (input_location
,
7188 gfor_fndecl_in_pack
, 1, desc
);
7190 if (fsym
&& fsym
->attr
.optional
&& sym
&& sym
->attr
.optional
)
7192 tmp
= gfc_conv_expr_present (sym
);
7193 ptr
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (se
->expr
),
7194 tmp
, fold_convert (TREE_TYPE (se
->expr
), ptr
),
7195 fold_convert (TREE_TYPE (se
->expr
), null_pointer_node
));
7198 ptr
= gfc_evaluate_now (ptr
, &se
->pre
);
7200 /* Use the packed data for the actual argument, except for contiguous arrays,
7201 where the descriptor's data component is set. */
7206 tmp
= build_fold_indirect_ref_loc (input_location
, desc
);
7207 gfc_conv_descriptor_data_set (&se
->pre
, tmp
, ptr
);
7210 if (gfc_option
.rtcheck
& GFC_RTCHECK_ARRAY_TEMPS
)
7214 if (fsym
&& proc_name
)
7215 asprintf (&msg
, "An array temporary was created for argument "
7216 "'%s' of procedure '%s'", fsym
->name
, proc_name
);
7218 asprintf (&msg
, "An array temporary was created");
7220 tmp
= build_fold_indirect_ref_loc (input_location
,
7222 tmp
= gfc_conv_array_data (tmp
);
7223 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
7224 fold_convert (TREE_TYPE (tmp
), ptr
), tmp
);
7226 if (fsym
&& fsym
->attr
.optional
&& sym
&& sym
->attr
.optional
)
7227 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
7229 gfc_conv_expr_present (sym
), tmp
);
7231 gfc_trans_runtime_check (false, true, tmp
, &se
->pre
,
7236 gfc_start_block (&block
);
7238 /* Copy the data back. */
7239 if (fsym
== NULL
|| fsym
->attr
.intent
!= INTENT_IN
)
7241 tmp
= build_call_expr_loc (input_location
,
7242 gfor_fndecl_in_unpack
, 2, desc
, ptr
);
7243 gfc_add_expr_to_block (&block
, tmp
);
7246 /* Free the temporary. */
7247 tmp
= gfc_call_free (convert (pvoid_type_node
, ptr
));
7248 gfc_add_expr_to_block (&block
, tmp
);
7250 stmt
= gfc_finish_block (&block
);
7252 gfc_init_block (&block
);
7253 /* Only if it was repacked. This code needs to be executed before the
7254 loop cleanup code. */
7255 tmp
= build_fold_indirect_ref_loc (input_location
,
7257 tmp
= gfc_conv_array_data (tmp
);
7258 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
7259 fold_convert (TREE_TYPE (tmp
), ptr
), tmp
);
7261 if (fsym
&& fsym
->attr
.optional
&& sym
&& sym
->attr
.optional
)
7262 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
7264 gfc_conv_expr_present (sym
), tmp
);
7266 tmp
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt (input_location
));
7268 gfc_add_expr_to_block (&block
, tmp
);
7269 gfc_add_block_to_block (&block
, &se
->post
);
7271 gfc_init_block (&se
->post
);
7273 /* Reset the descriptor pointer. */
7276 tmp
= build_fold_indirect_ref_loc (input_location
, desc
);
7277 gfc_conv_descriptor_data_set (&se
->post
, tmp
, origptr
);
7280 gfc_add_block_to_block (&se
->post
, &block
);
7285 /* Generate code to deallocate an array, if it is allocated. */
7288 gfc_trans_dealloc_allocated (tree descriptor
, bool coarray
, gfc_expr
*expr
)
7294 gfc_start_block (&block
);
7296 var
= gfc_conv_descriptor_data_get (descriptor
);
7299 /* Call array_deallocate with an int * present in the second argument.
7300 Although it is ignored here, it's presence ensures that arrays that
7301 are already deallocated are ignored. */
7302 tmp
= gfc_deallocate_with_status (coarray
? descriptor
: var
, NULL_TREE
,
7303 NULL_TREE
, NULL_TREE
, NULL_TREE
, true,
7305 gfc_add_expr_to_block (&block
, tmp
);
7307 /* Zero the data pointer. */
7308 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
7309 var
, build_int_cst (TREE_TYPE (var
), 0));
7310 gfc_add_expr_to_block (&block
, tmp
);
7312 return gfc_finish_block (&block
);
7316 /* This helper function calculates the size in words of a full array. */
7319 get_full_array_size (stmtblock_t
*block
, tree decl
, int rank
)
7324 idx
= gfc_rank_cst
[rank
- 1];
7325 nelems
= gfc_conv_descriptor_ubound_get (decl
, idx
);
7326 tmp
= gfc_conv_descriptor_lbound_get (decl
, idx
);
7327 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
7329 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
7330 tmp
, gfc_index_one_node
);
7331 tmp
= gfc_evaluate_now (tmp
, block
);
7333 nelems
= gfc_conv_descriptor_stride_get (decl
, idx
);
7334 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
7336 return gfc_evaluate_now (tmp
, block
);
7340 /* Allocate dest to the same size as src, and copy src -> dest.
7341 If no_malloc is set, only the copy is done. */
7344 duplicate_allocatable (tree dest
, tree src
, tree type
, int rank
,
7354 /* If the source is null, set the destination to null. Then,
7355 allocate memory to the destination. */
7356 gfc_init_block (&block
);
7358 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest
)))
7360 tmp
= null_pointer_node
;
7361 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, type
, dest
, tmp
);
7362 gfc_add_expr_to_block (&block
, tmp
);
7363 null_data
= gfc_finish_block (&block
);
7365 gfc_init_block (&block
);
7366 size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
7369 tmp
= gfc_call_malloc (&block
, type
, size
);
7370 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
7371 dest
, fold_convert (type
, tmp
));
7372 gfc_add_expr_to_block (&block
, tmp
);
7375 tmp
= builtin_decl_explicit (BUILT_IN_MEMCPY
);
7376 tmp
= build_call_expr_loc (input_location
, tmp
, 3, dest
, src
,
7377 fold_convert (size_type_node
, size
));
7381 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
7382 null_data
= gfc_finish_block (&block
);
7384 gfc_init_block (&block
);
7386 nelems
= get_full_array_size (&block
, src
, rank
);
7388 nelems
= gfc_index_one_node
;
7390 tmp
= fold_convert (gfc_array_index_type
,
7391 TYPE_SIZE_UNIT (gfc_get_element_type (type
)));
7392 size
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
7396 tmp
= TREE_TYPE (gfc_conv_descriptor_data_get (src
));
7397 tmp
= gfc_call_malloc (&block
, tmp
, size
);
7398 gfc_conv_descriptor_data_set (&block
, dest
, tmp
);
7401 /* We know the temporary and the value will be the same length,
7402 so can use memcpy. */
7403 tmp
= builtin_decl_explicit (BUILT_IN_MEMCPY
);
7404 tmp
= build_call_expr_loc (input_location
,
7405 tmp
, 3, gfc_conv_descriptor_data_get (dest
),
7406 gfc_conv_descriptor_data_get (src
),
7407 fold_convert (size_type_node
, size
));
7410 gfc_add_expr_to_block (&block
, tmp
);
7411 tmp
= gfc_finish_block (&block
);
7413 /* Null the destination if the source is null; otherwise do
7414 the allocate and copy. */
7415 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src
)))
7418 null_cond
= gfc_conv_descriptor_data_get (src
);
7420 null_cond
= convert (pvoid_type_node
, null_cond
);
7421 null_cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
7422 null_cond
, null_pointer_node
);
7423 return build3_v (COND_EXPR
, null_cond
, tmp
, null_data
);
7427 /* Allocate dest to the same size as src, and copy data src -> dest. */
7430 gfc_duplicate_allocatable (tree dest
, tree src
, tree type
, int rank
)
7432 return duplicate_allocatable (dest
, src
, type
, rank
, false);
7436 /* Copy data src -> dest. */
7439 gfc_copy_allocatable_data (tree dest
, tree src
, tree type
, int rank
)
7441 return duplicate_allocatable (dest
, src
, type
, rank
, true);
7445 /* Recursively traverse an object of derived type, generating code to
7446 deallocate, nullify or copy allocatable components. This is the work horse
7447 function for the functions named in this enum. */
7449 enum {DEALLOCATE_ALLOC_COMP
= 1, DEALLOCATE_ALLOC_COMP_NO_CAF
,
7450 NULLIFY_ALLOC_COMP
, COPY_ALLOC_COMP
, COPY_ONLY_ALLOC_COMP
,
7451 COPY_ALLOC_COMP_CAF
};
7454 structure_alloc_comps (gfc_symbol
* der_type
, tree decl
,
7455 tree dest
, int rank
, int purpose
)
7459 stmtblock_t fnblock
;
7460 stmtblock_t loopbody
;
7461 stmtblock_t tmpblock
;
7472 tree null_cond
= NULL_TREE
;
7473 bool called_dealloc_with_status
;
7475 gfc_init_block (&fnblock
);
7477 decl_type
= TREE_TYPE (decl
);
7479 if ((POINTER_TYPE_P (decl_type
) && rank
!= 0)
7480 || (TREE_CODE (decl_type
) == REFERENCE_TYPE
&& rank
== 0))
7481 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
7483 /* Just in case in gets dereferenced. */
7484 decl_type
= TREE_TYPE (decl
);
7486 /* If this an array of derived types with allocatable components
7487 build a loop and recursively call this function. */
7488 if (TREE_CODE (decl_type
) == ARRAY_TYPE
7489 || (GFC_DESCRIPTOR_TYPE_P (decl_type
) && rank
!= 0))
7491 tmp
= gfc_conv_array_data (decl
);
7492 var
= build_fold_indirect_ref_loc (input_location
,
7495 /* Get the number of elements - 1 and set the counter. */
7496 if (GFC_DESCRIPTOR_TYPE_P (decl_type
))
7498 /* Use the descriptor for an allocatable array. Since this
7499 is a full array reference, we only need the descriptor
7500 information from dimension = rank. */
7501 tmp
= get_full_array_size (&fnblock
, decl
, rank
);
7502 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
7503 gfc_array_index_type
, tmp
,
7504 gfc_index_one_node
);
7506 null_cond
= gfc_conv_descriptor_data_get (decl
);
7507 null_cond
= fold_build2_loc (input_location
, NE_EXPR
,
7508 boolean_type_node
, null_cond
,
7509 build_int_cst (TREE_TYPE (null_cond
), 0));
7513 /* Otherwise use the TYPE_DOMAIN information. */
7514 tmp
= array_type_nelts (decl_type
);
7515 tmp
= fold_convert (gfc_array_index_type
, tmp
);
7518 /* Remember that this is, in fact, the no. of elements - 1. */
7519 nelems
= gfc_evaluate_now (tmp
, &fnblock
);
7520 index
= gfc_create_var (gfc_array_index_type
, "S");
7522 /* Build the body of the loop. */
7523 gfc_init_block (&loopbody
);
7525 vref
= gfc_build_array_ref (var
, index
, NULL
);
7527 if (purpose
== COPY_ALLOC_COMP
)
7529 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest
)))
7531 tmp
= gfc_duplicate_allocatable (dest
, decl
, decl_type
, rank
);
7532 gfc_add_expr_to_block (&fnblock
, tmp
);
7534 tmp
= build_fold_indirect_ref_loc (input_location
,
7535 gfc_conv_array_data (dest
));
7536 dref
= gfc_build_array_ref (tmp
, index
, NULL
);
7537 tmp
= structure_alloc_comps (der_type
, vref
, dref
, rank
, purpose
);
7539 else if (purpose
== COPY_ONLY_ALLOC_COMP
)
7541 tmp
= build_fold_indirect_ref_loc (input_location
,
7542 gfc_conv_array_data (dest
));
7543 dref
= gfc_build_array_ref (tmp
, index
, NULL
);
7544 tmp
= structure_alloc_comps (der_type
, vref
, dref
, rank
,
7548 tmp
= structure_alloc_comps (der_type
, vref
, NULL_TREE
, rank
, purpose
);
7550 gfc_add_expr_to_block (&loopbody
, tmp
);
7552 /* Build the loop and return. */
7553 gfc_init_loopinfo (&loop
);
7555 loop
.from
[0] = gfc_index_zero_node
;
7556 loop
.loopvar
[0] = index
;
7557 loop
.to
[0] = nelems
;
7558 gfc_trans_scalarizing_loops (&loop
, &loopbody
);
7559 gfc_add_block_to_block (&fnblock
, &loop
.pre
);
7561 tmp
= gfc_finish_block (&fnblock
);
7562 if (null_cond
!= NULL_TREE
)
7563 tmp
= build3_v (COND_EXPR
, null_cond
, tmp
,
7564 build_empty_stmt (input_location
));
7569 /* Otherwise, act on the components or recursively call self to
7570 act on a chain of components. */
7571 for (c
= der_type
->components
; c
; c
= c
->next
)
7573 bool cmp_has_alloc_comps
= (c
->ts
.type
== BT_DERIVED
7574 || c
->ts
.type
== BT_CLASS
)
7575 && c
->ts
.u
.derived
->attr
.alloc_comp
;
7576 cdecl = c
->backend_decl
;
7577 ctype
= TREE_TYPE (cdecl);
7581 case DEALLOCATE_ALLOC_COMP
:
7582 case DEALLOCATE_ALLOC_COMP_NO_CAF
:
7584 /* gfc_deallocate_scalar_with_status calls gfc_deallocate_alloc_comp
7585 (i.e. this function) so generate all the calls and suppress the
7586 recursion from here, if necessary. */
7587 called_dealloc_with_status
= false;
7588 gfc_init_block (&tmpblock
);
7590 if ((c
->ts
.type
== BT_DERIVED
&& !c
->attr
.pointer
)
7591 || (c
->ts
.type
== BT_CLASS
&& !CLASS_DATA (c
)->attr
.class_pointer
))
7593 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7594 decl
, cdecl, NULL_TREE
);
7596 /* The finalizer frees allocatable components. */
7597 called_dealloc_with_status
7598 = gfc_add_comp_finalizer_call (&tmpblock
, comp
, c
,
7599 purpose
== DEALLOCATE_ALLOC_COMP
);
7604 if (c
->attr
.allocatable
&& !c
->attr
.proc_pointer
7605 && (c
->attr
.dimension
7606 || (c
->attr
.codimension
7607 && purpose
!= DEALLOCATE_ALLOC_COMP_NO_CAF
)))
7609 if (comp
== NULL_TREE
)
7610 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7611 decl
, cdecl, NULL_TREE
);
7612 tmp
= gfc_trans_dealloc_allocated (comp
, c
->attr
.codimension
, NULL
);
7613 gfc_add_expr_to_block (&tmpblock
, tmp
);
7615 else if (c
->attr
.allocatable
&& !c
->attr
.codimension
)
7617 /* Allocatable scalar components. */
7618 if (comp
== NULL_TREE
)
7619 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7620 decl
, cdecl, NULL_TREE
);
7622 tmp
= gfc_deallocate_scalar_with_status (comp
, NULL
, true, NULL
,
7624 gfc_add_expr_to_block (&tmpblock
, tmp
);
7625 called_dealloc_with_status
= true;
7627 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
7628 void_type_node
, comp
,
7629 build_int_cst (TREE_TYPE (comp
), 0));
7630 gfc_add_expr_to_block (&tmpblock
, tmp
);
7632 else if (c
->ts
.type
== BT_CLASS
&& CLASS_DATA (c
)->attr
.allocatable
7633 && (!CLASS_DATA (c
)->attr
.codimension
7634 || purpose
!= DEALLOCATE_ALLOC_COMP_NO_CAF
))
7636 /* Allocatable CLASS components. */
7638 /* Add reference to '_data' component. */
7639 tmp
= CLASS_DATA (c
)->backend_decl
;
7640 comp
= fold_build3_loc (input_location
, COMPONENT_REF
,
7641 TREE_TYPE (tmp
), comp
, tmp
, NULL_TREE
);
7643 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp
)))
7644 tmp
= gfc_trans_dealloc_allocated (comp
,
7645 CLASS_DATA (c
)->attr
.codimension
, NULL
);
7648 tmp
= gfc_deallocate_scalar_with_status (comp
, NULL_TREE
, true, NULL
,
7649 CLASS_DATA (c
)->ts
);
7650 gfc_add_expr_to_block (&tmpblock
, tmp
);
7651 called_dealloc_with_status
= true;
7653 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
7654 void_type_node
, comp
,
7655 build_int_cst (TREE_TYPE (comp
), 0));
7657 gfc_add_expr_to_block (&tmpblock
, tmp
);
7660 if (cmp_has_alloc_comps
7662 && !called_dealloc_with_status
)
7664 /* Do not deallocate the components of ultimate pointer
7665 components or iteratively call self if call has been made
7666 to gfc_trans_dealloc_allocated */
7667 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7668 decl
, cdecl, NULL_TREE
);
7669 rank
= c
->as
? c
->as
->rank
: 0;
7670 tmp
= structure_alloc_comps (c
->ts
.u
.derived
, comp
, NULL_TREE
,
7672 gfc_add_expr_to_block (&fnblock
, tmp
);
7675 /* Now add the deallocation of this component. */
7676 gfc_add_block_to_block (&fnblock
, &tmpblock
);
7679 case NULLIFY_ALLOC_COMP
:
7680 if (c
->attr
.pointer
)
7682 else if (c
->attr
.allocatable
7683 && (c
->attr
.dimension
|| c
->attr
.codimension
))
7685 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7686 decl
, cdecl, NULL_TREE
);
7687 gfc_conv_descriptor_data_set (&fnblock
, comp
, null_pointer_node
);
7689 else if (c
->attr
.allocatable
)
7691 /* Allocatable scalar components. */
7692 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7693 decl
, cdecl, NULL_TREE
);
7694 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
7695 void_type_node
, comp
,
7696 build_int_cst (TREE_TYPE (comp
), 0));
7697 gfc_add_expr_to_block (&fnblock
, tmp
);
7699 else if (c
->ts
.type
== BT_CLASS
&& CLASS_DATA (c
)->attr
.allocatable
)
7701 /* Allocatable CLASS components. */
7702 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7703 decl
, cdecl, NULL_TREE
);
7704 /* Add reference to '_data' component. */
7705 tmp
= CLASS_DATA (c
)->backend_decl
;
7706 comp
= fold_build3_loc (input_location
, COMPONENT_REF
,
7707 TREE_TYPE (tmp
), comp
, tmp
, NULL_TREE
);
7708 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp
)))
7709 gfc_conv_descriptor_data_set (&fnblock
, comp
, null_pointer_node
);
7712 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
7713 void_type_node
, comp
,
7714 build_int_cst (TREE_TYPE (comp
), 0));
7715 gfc_add_expr_to_block (&fnblock
, tmp
);
7718 else if (cmp_has_alloc_comps
)
7720 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
,
7721 decl
, cdecl, NULL_TREE
);
7722 rank
= c
->as
? c
->as
->rank
: 0;
7723 tmp
= structure_alloc_comps (c
->ts
.u
.derived
, comp
, NULL_TREE
,
7725 gfc_add_expr_to_block (&fnblock
, tmp
);
7729 case COPY_ALLOC_COMP_CAF
:
7730 if (!c
->attr
.codimension
7731 && (c
->ts
.type
!= BT_CLASS
|| CLASS_DATA (c
)->attr
.coarray_comp
)
7732 && (c
->ts
.type
!= BT_DERIVED
7733 || !c
->ts
.u
.derived
->attr
.coarray_comp
))
7736 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
, decl
,
7738 dcmp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
, dest
,
7741 if (c
->attr
.codimension
)
7743 if (c
->ts
.type
== BT_CLASS
)
7745 comp
= gfc_class_data_get (comp
);
7746 dcmp
= gfc_class_data_get (dcmp
);
7748 gfc_conv_descriptor_data_set (&fnblock
, dcmp
,
7749 gfc_conv_descriptor_data_get (comp
));
7753 tmp
= structure_alloc_comps (c
->ts
.u
.derived
, comp
, dcmp
,
7755 gfc_add_expr_to_block (&fnblock
, tmp
);
7760 case COPY_ALLOC_COMP
:
7761 if (c
->attr
.pointer
)
7764 /* We need source and destination components. */
7765 comp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
, decl
,
7767 dcmp
= fold_build3_loc (input_location
, COMPONENT_REF
, ctype
, dest
,
7769 dcmp
= fold_convert (TREE_TYPE (comp
), dcmp
);
7771 if (c
->ts
.type
== BT_CLASS
&& CLASS_DATA (c
)->attr
.allocatable
)
7779 dst_data
= gfc_class_data_get (dcmp
);
7780 src_data
= gfc_class_data_get (comp
);
7781 size
= fold_convert (size_type_node
, gfc_vtable_size_get (comp
));
7783 if (CLASS_DATA (c
)->attr
.dimension
)
7785 nelems
= gfc_conv_descriptor_size (src_data
,
7786 CLASS_DATA (c
)->as
->rank
);
7787 size
= fold_build2_loc (input_location
, MULT_EXPR
,
7788 size_type_node
, size
,
7789 fold_convert (size_type_node
,
7793 nelems
= build_int_cst (size_type_node
, 1);
7795 if (CLASS_DATA (c
)->attr
.dimension
7796 || CLASS_DATA (c
)->attr
.codimension
)
7798 src_data
= gfc_conv_descriptor_data_get (src_data
);
7799 dst_data
= gfc_conv_descriptor_data_get (dst_data
);
7802 gfc_init_block (&tmpblock
);
7804 /* Coarray component have to have the same allocation status and
7805 shape/type-parameter/effective-type on the LHS and RHS of an
7806 intrinsic assignment. Hence, we did not deallocated them - and
7807 do not allocate them here. */
7808 if (!CLASS_DATA (c
)->attr
.codimension
)
7810 ftn_tree
= builtin_decl_explicit (BUILT_IN_MALLOC
);
7811 tmp
= build_call_expr_loc (input_location
, ftn_tree
, 1, size
);
7812 gfc_add_modify (&tmpblock
, dst_data
,
7813 fold_convert (TREE_TYPE (dst_data
), tmp
));
7816 tmp
= gfc_copy_class_to_class (comp
, dcmp
, nelems
);
7817 gfc_add_expr_to_block (&tmpblock
, tmp
);
7818 tmp
= gfc_finish_block (&tmpblock
);
7820 gfc_init_block (&tmpblock
);
7821 gfc_add_modify (&tmpblock
, dst_data
,
7822 fold_convert (TREE_TYPE (dst_data
),
7823 null_pointer_node
));
7824 null_data
= gfc_finish_block (&tmpblock
);
7826 null_cond
= fold_build2_loc (input_location
, NE_EXPR
,
7827 boolean_type_node
, src_data
,
7830 gfc_add_expr_to_block (&fnblock
, build3_v (COND_EXPR
, null_cond
,
7835 if (c
->attr
.allocatable
&& !c
->attr
.proc_pointer
7836 && !cmp_has_alloc_comps
)
7838 rank
= c
->as
? c
->as
->rank
: 0;
7839 if (c
->attr
.codimension
)
7840 tmp
= gfc_copy_allocatable_data (dcmp
, comp
, ctype
, rank
);
7842 tmp
= gfc_duplicate_allocatable (dcmp
, comp
, ctype
, rank
);
7843 gfc_add_expr_to_block (&fnblock
, tmp
);
7846 if (cmp_has_alloc_comps
)
7848 rank
= c
->as
? c
->as
->rank
: 0;
7849 tmp
= fold_convert (TREE_TYPE (dcmp
), comp
);
7850 gfc_add_modify (&fnblock
, dcmp
, tmp
);
7851 tmp
= structure_alloc_comps (c
->ts
.u
.derived
, comp
, dcmp
,
7853 gfc_add_expr_to_block (&fnblock
, tmp
);
7863 return gfc_finish_block (&fnblock
);
7866 /* Recursively traverse an object of derived type, generating code to
7867 nullify allocatable components. */
7870 gfc_nullify_alloc_comp (gfc_symbol
* der_type
, tree decl
, int rank
)
7872 return structure_alloc_comps (der_type
, decl
, NULL_TREE
, rank
,
7873 NULLIFY_ALLOC_COMP
);
7877 /* Recursively traverse an object of derived type, generating code to
7878 deallocate allocatable components. */
7881 gfc_deallocate_alloc_comp (gfc_symbol
* der_type
, tree decl
, int rank
)
7883 return structure_alloc_comps (der_type
, decl
, NULL_TREE
, rank
,
7884 DEALLOCATE_ALLOC_COMP
);
7888 /* Recursively traverse an object of derived type, generating code to
7889 deallocate allocatable components. But do not deallocate coarrays.
7890 To be used for intrinsic assignment, which may not change the allocation
7891 status of coarrays. */
7894 gfc_deallocate_alloc_comp_no_caf (gfc_symbol
* der_type
, tree decl
, int rank
)
7896 return structure_alloc_comps (der_type
, decl
, NULL_TREE
, rank
,
7897 DEALLOCATE_ALLOC_COMP_NO_CAF
);
7902 gfc_reassign_alloc_comp_caf (gfc_symbol
*der_type
, tree decl
, tree dest
)
7904 return structure_alloc_comps (der_type
, decl
, dest
, 0, COPY_ALLOC_COMP_CAF
);
7908 /* Recursively traverse an object of derived type, generating code to
7909 copy it and its allocatable components. */
7912 gfc_copy_alloc_comp (gfc_symbol
* der_type
, tree decl
, tree dest
, int rank
)
7914 return structure_alloc_comps (der_type
, decl
, dest
, rank
, COPY_ALLOC_COMP
);
7918 /* Recursively traverse an object of derived type, generating code to
7919 copy only its allocatable components. */
7922 gfc_copy_only_alloc_comp (gfc_symbol
* der_type
, tree decl
, tree dest
, int rank
)
7924 return structure_alloc_comps (der_type
, decl
, dest
, rank
, COPY_ONLY_ALLOC_COMP
);
7928 /* Returns the value of LBOUND for an expression. This could be broken out
7929 from gfc_conv_intrinsic_bound but this seemed to be simpler. This is
7930 called by gfc_alloc_allocatable_for_assignment. */
7932 get_std_lbound (gfc_expr
*expr
, tree desc
, int dim
, bool assumed_size
)
7937 tree cond
, cond1
, cond3
, cond4
;
7941 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc
)))
7943 tmp
= gfc_rank_cst
[dim
];
7944 lbound
= gfc_conv_descriptor_lbound_get (desc
, tmp
);
7945 ubound
= gfc_conv_descriptor_ubound_get (desc
, tmp
);
7946 stride
= gfc_conv_descriptor_stride_get (desc
, tmp
);
7947 cond1
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
7949 cond3
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
7950 stride
, gfc_index_zero_node
);
7951 cond3
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
7952 boolean_type_node
, cond3
, cond1
);
7953 cond4
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
7954 stride
, gfc_index_zero_node
);
7956 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
7957 tmp
, build_int_cst (gfc_array_index_type
,
7960 cond
= boolean_false_node
;
7962 cond1
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
7963 boolean_type_node
, cond3
, cond4
);
7964 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
7965 boolean_type_node
, cond
, cond1
);
7967 return fold_build3_loc (input_location
, COND_EXPR
,
7968 gfc_array_index_type
, cond
,
7969 lbound
, gfc_index_one_node
);
7972 if (expr
->expr_type
== EXPR_FUNCTION
)
7974 /* A conversion function, so use the argument. */
7975 gcc_assert (expr
->value
.function
.isym
7976 && expr
->value
.function
.isym
->conversion
);
7977 expr
= expr
->value
.function
.actual
->expr
;
7980 if (expr
->expr_type
== EXPR_VARIABLE
)
7982 tmp
= TREE_TYPE (expr
->symtree
->n
.sym
->backend_decl
);
7983 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
7985 if (ref
->type
== REF_COMPONENT
7986 && ref
->u
.c
.component
->as
7988 && ref
->next
->u
.ar
.type
== AR_FULL
)
7989 tmp
= TREE_TYPE (ref
->u
.c
.component
->backend_decl
);
7991 return GFC_TYPE_ARRAY_LBOUND(tmp
, dim
);
7994 return gfc_index_one_node
;
7998 /* Returns true if an expression represents an lhs that can be reallocated
8002 gfc_is_reallocatable_lhs (gfc_expr
*expr
)
8009 /* An allocatable variable. */
8010 if (expr
->symtree
->n
.sym
->attr
.allocatable
8012 && expr
->ref
->type
== REF_ARRAY
8013 && expr
->ref
->u
.ar
.type
== AR_FULL
)
8016 /* All that can be left are allocatable components. */
8017 if ((expr
->symtree
->n
.sym
->ts
.type
!= BT_DERIVED
8018 && expr
->symtree
->n
.sym
->ts
.type
!= BT_CLASS
)
8019 || !expr
->symtree
->n
.sym
->ts
.u
.derived
->attr
.alloc_comp
)
8022 /* Find a component ref followed by an array reference. */
8023 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
8025 && ref
->type
== REF_COMPONENT
8026 && ref
->next
->type
== REF_ARRAY
8027 && !ref
->next
->next
)
8033 /* Return true if valid reallocatable lhs. */
8034 if (ref
->u
.c
.component
->attr
.allocatable
8035 && ref
->next
->u
.ar
.type
== AR_FULL
)
8042 /* Allocate the lhs of an assignment to an allocatable array, otherwise
8046 gfc_alloc_allocatable_for_assignment (gfc_loopinfo
*loop
,
8050 stmtblock_t realloc_block
;
8051 stmtblock_t alloc_block
;
8055 gfc_array_info
*linfo
;
8076 gfc_array_spec
* as
;
8078 /* x = f(...) with x allocatable. In this case, expr1 is the rhs.
8079 Find the lhs expression in the loop chain and set expr1 and
8080 expr2 accordingly. */
8081 if (expr1
->expr_type
== EXPR_FUNCTION
&& expr2
== NULL
)
8084 /* Find the ss for the lhs. */
8086 for (; lss
&& lss
!= gfc_ss_terminator
; lss
= lss
->loop_chain
)
8087 if (lss
->info
->expr
&& lss
->info
->expr
->expr_type
== EXPR_VARIABLE
)
8089 if (lss
== gfc_ss_terminator
)
8091 expr1
= lss
->info
->expr
;
8094 /* Bail out if this is not a valid allocate on assignment. */
8095 if (!gfc_is_reallocatable_lhs (expr1
)
8096 || (expr2
&& !expr2
->rank
))
8099 /* Find the ss for the lhs. */
8101 for (; lss
&& lss
!= gfc_ss_terminator
; lss
= lss
->loop_chain
)
8102 if (lss
->info
->expr
== expr1
)
8105 if (lss
== gfc_ss_terminator
)
8108 linfo
= &lss
->info
->data
.array
;
8110 /* Find an ss for the rhs. For operator expressions, we see the
8111 ss's for the operands. Any one of these will do. */
8113 for (; rss
&& rss
!= gfc_ss_terminator
; rss
= rss
->loop_chain
)
8114 if (rss
->info
->expr
!= expr1
&& rss
!= loop
->temp_ss
)
8117 if (expr2
&& rss
== gfc_ss_terminator
)
8120 gfc_start_block (&fblock
);
8122 /* Since the lhs is allocatable, this must be a descriptor type.
8123 Get the data and array size. */
8124 desc
= linfo
->descriptor
;
8125 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc
)));
8126 array1
= gfc_conv_descriptor_data_get (desc
);
8128 /* 7.4.1.3 "If variable is an allocated allocatable variable, it is
8129 deallocated if expr is an array of different shape or any of the
8130 corresponding length type parameter values of variable and expr
8131 differ." This assures F95 compatibility. */
8132 jump_label1
= gfc_build_label_decl (NULL_TREE
);
8133 jump_label2
= gfc_build_label_decl (NULL_TREE
);
8135 /* Allocate if data is NULL. */
8136 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
8137 array1
, build_int_cst (TREE_TYPE (array1
), 0));
8138 tmp
= build3_v (COND_EXPR
, cond
,
8139 build1_v (GOTO_EXPR
, jump_label1
),
8140 build_empty_stmt (input_location
));
8141 gfc_add_expr_to_block (&fblock
, tmp
);
8143 /* Get arrayspec if expr is a full array. */
8144 if (expr2
&& expr2
->expr_type
== EXPR_FUNCTION
8145 && expr2
->value
.function
.isym
8146 && expr2
->value
.function
.isym
->conversion
)
8148 /* For conversion functions, take the arg. */
8149 gfc_expr
*arg
= expr2
->value
.function
.actual
->expr
;
8150 as
= gfc_get_full_arrayspec_from_expr (arg
);
8153 as
= gfc_get_full_arrayspec_from_expr (expr2
);
8157 /* If the lhs shape is not the same as the rhs jump to setting the
8158 bounds and doing the reallocation....... */
8159 for (n
= 0; n
< expr1
->rank
; n
++)
8161 /* Check the shape. */
8162 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[n
]);
8163 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[n
]);
8164 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8165 gfc_array_index_type
,
8166 loop
->to
[n
], loop
->from
[n
]);
8167 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
8168 gfc_array_index_type
,
8170 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8171 gfc_array_index_type
,
8173 cond
= fold_build2_loc (input_location
, NE_EXPR
,
8175 tmp
, gfc_index_zero_node
);
8176 tmp
= build3_v (COND_EXPR
, cond
,
8177 build1_v (GOTO_EXPR
, jump_label1
),
8178 build_empty_stmt (input_location
));
8179 gfc_add_expr_to_block (&fblock
, tmp
);
8182 /* ....else jump past the (re)alloc code. */
8183 tmp
= build1_v (GOTO_EXPR
, jump_label2
);
8184 gfc_add_expr_to_block (&fblock
, tmp
);
8186 /* Add the label to start automatic (re)allocation. */
8187 tmp
= build1_v (LABEL_EXPR
, jump_label1
);
8188 gfc_add_expr_to_block (&fblock
, tmp
);
8190 size1
= gfc_conv_descriptor_size (desc
, expr1
->rank
);
8192 /* Get the rhs size. Fix both sizes. */
8194 desc2
= rss
->info
->data
.array
.descriptor
;
8197 size2
= gfc_index_one_node
;
8198 for (n
= 0; n
< expr2
->rank
; n
++)
8200 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8201 gfc_array_index_type
,
8202 loop
->to
[n
], loop
->from
[n
]);
8203 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
8204 gfc_array_index_type
,
8205 tmp
, gfc_index_one_node
);
8206 size2
= fold_build2_loc (input_location
, MULT_EXPR
,
8207 gfc_array_index_type
,
8211 size1
= gfc_evaluate_now (size1
, &fblock
);
8212 size2
= gfc_evaluate_now (size2
, &fblock
);
8214 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
8216 neq_size
= gfc_evaluate_now (cond
, &fblock
);
8218 /* Deallocation of allocatable components will have to occur on
8219 reallocation. Fix the old descriptor now. */
8220 if ((expr1
->ts
.type
== BT_DERIVED
)
8221 && expr1
->ts
.u
.derived
->attr
.alloc_comp
)
8222 old_desc
= gfc_evaluate_now (desc
, &fblock
);
8224 old_desc
= NULL_TREE
;
8226 /* Now modify the lhs descriptor and the associated scalarizer
8227 variables. F2003 7.4.1.3: "If variable is or becomes an
8228 unallocated allocatable variable, then it is allocated with each
8229 deferred type parameter equal to the corresponding type parameters
8230 of expr , with the shape of expr , and with each lower bound equal
8231 to the corresponding element of LBOUND(expr)."
8232 Reuse size1 to keep a dimension-by-dimension track of the
8233 stride of the new array. */
8234 size1
= gfc_index_one_node
;
8235 offset
= gfc_index_zero_node
;
8237 for (n
= 0; n
< expr2
->rank
; n
++)
8239 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8240 gfc_array_index_type
,
8241 loop
->to
[n
], loop
->from
[n
]);
8242 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
8243 gfc_array_index_type
,
8244 tmp
, gfc_index_one_node
);
8246 lbound
= gfc_index_one_node
;
8251 lbd
= get_std_lbound (expr2
, desc2
, n
,
8252 as
->type
== AS_ASSUMED_SIZE
);
8253 ubound
= fold_build2_loc (input_location
,
8255 gfc_array_index_type
,
8257 ubound
= fold_build2_loc (input_location
,
8259 gfc_array_index_type
,
8264 gfc_conv_descriptor_lbound_set (&fblock
, desc
,
8267 gfc_conv_descriptor_ubound_set (&fblock
, desc
,
8270 gfc_conv_descriptor_stride_set (&fblock
, desc
,
8273 lbound
= gfc_conv_descriptor_lbound_get (desc
,
8275 tmp2
= fold_build2_loc (input_location
, MULT_EXPR
,
8276 gfc_array_index_type
,
8278 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
8279 gfc_array_index_type
,
8281 size1
= fold_build2_loc (input_location
, MULT_EXPR
,
8282 gfc_array_index_type
,
8286 /* Set the lhs descriptor and scalarizer offsets. For rank > 1,
8287 the array offset is saved and the info.offset is used for a
8288 running offset. Use the saved_offset instead. */
8289 tmp
= gfc_conv_descriptor_offset (desc
);
8290 gfc_add_modify (&fblock
, tmp
, offset
);
8291 if (linfo
->saved_offset
8292 && TREE_CODE (linfo
->saved_offset
) == VAR_DECL
)
8293 gfc_add_modify (&fblock
, linfo
->saved_offset
, tmp
);
8295 /* Now set the deltas for the lhs. */
8296 for (n
= 0; n
< expr1
->rank
; n
++)
8298 tmp
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[n
]);
8300 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8301 gfc_array_index_type
, tmp
,
8303 if (linfo
->delta
[dim
]
8304 && TREE_CODE (linfo
->delta
[dim
]) == VAR_DECL
)
8305 gfc_add_modify (&fblock
, linfo
->delta
[dim
], tmp
);
8308 /* Get the new lhs size in bytes. */
8309 if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.deferred
)
8311 tmp
= expr2
->ts
.u
.cl
->backend_decl
;
8312 gcc_assert (expr1
->ts
.u
.cl
->backend_decl
);
8313 tmp
= fold_convert (TREE_TYPE (expr1
->ts
.u
.cl
->backend_decl
), tmp
);
8314 gfc_add_modify (&fblock
, expr1
->ts
.u
.cl
->backend_decl
, tmp
);
8316 else if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.u
.cl
->backend_decl
)
8318 tmp
= TYPE_SIZE_UNIT (TREE_TYPE (gfc_typenode_for_spec (&expr1
->ts
)));
8319 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
8320 gfc_array_index_type
, tmp
,
8321 expr1
->ts
.u
.cl
->backend_decl
);
8324 tmp
= TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1
->ts
));
8325 tmp
= fold_convert (gfc_array_index_type
, tmp
);
8326 size2
= fold_build2_loc (input_location
, MULT_EXPR
,
8327 gfc_array_index_type
,
8329 size2
= fold_convert (size_type_node
, size2
);
8330 size2
= fold_build2_loc (input_location
, MAX_EXPR
, size_type_node
,
8331 size2
, size_one_node
);
8332 size2
= gfc_evaluate_now (size2
, &fblock
);
8334 /* Realloc expression. Note that the scalarizer uses desc.data
8335 in the array reference - (*desc.data)[<element>]. */
8336 gfc_init_block (&realloc_block
);
8338 if ((expr1
->ts
.type
== BT_DERIVED
)
8339 && expr1
->ts
.u
.derived
->attr
.alloc_comp
)
8341 tmp
= gfc_deallocate_alloc_comp_no_caf (expr1
->ts
.u
.derived
, old_desc
,
8343 gfc_add_expr_to_block (&realloc_block
, tmp
);
8346 tmp
= build_call_expr_loc (input_location
,
8347 builtin_decl_explicit (BUILT_IN_REALLOC
), 2,
8348 fold_convert (pvoid_type_node
, array1
),
8350 gfc_conv_descriptor_data_set (&realloc_block
,
8353 if ((expr1
->ts
.type
== BT_DERIVED
)
8354 && expr1
->ts
.u
.derived
->attr
.alloc_comp
)
8356 tmp
= gfc_nullify_alloc_comp (expr1
->ts
.u
.derived
, desc
,
8358 gfc_add_expr_to_block (&realloc_block
, tmp
);
8361 realloc_expr
= gfc_finish_block (&realloc_block
);
8363 /* Only reallocate if sizes are different. */
8364 tmp
= build3_v (COND_EXPR
, neq_size
, realloc_expr
,
8365 build_empty_stmt (input_location
));
8369 /* Malloc expression. */
8370 gfc_init_block (&alloc_block
);
8371 tmp
= build_call_expr_loc (input_location
,
8372 builtin_decl_explicit (BUILT_IN_MALLOC
),
8374 gfc_conv_descriptor_data_set (&alloc_block
,
8376 tmp
= gfc_conv_descriptor_dtype (desc
);
8377 gfc_add_modify (&alloc_block
, tmp
, gfc_get_dtype (TREE_TYPE (desc
)));
8378 if ((expr1
->ts
.type
== BT_DERIVED
)
8379 && expr1
->ts
.u
.derived
->attr
.alloc_comp
)
8381 tmp
= gfc_nullify_alloc_comp (expr1
->ts
.u
.derived
, desc
,
8383 gfc_add_expr_to_block (&alloc_block
, tmp
);
8385 alloc_expr
= gfc_finish_block (&alloc_block
);
8387 /* Malloc if not allocated; realloc otherwise. */
8388 tmp
= build_int_cst (TREE_TYPE (array1
), 0);
8389 cond
= fold_build2_loc (input_location
, EQ_EXPR
,
8392 tmp
= build3_v (COND_EXPR
, cond
, alloc_expr
, realloc_expr
);
8393 gfc_add_expr_to_block (&fblock
, tmp
);
8395 /* Make sure that the scalarizer data pointer is updated. */
8397 && TREE_CODE (linfo
->data
) == VAR_DECL
)
8399 tmp
= gfc_conv_descriptor_data_get (desc
);
8400 gfc_add_modify (&fblock
, linfo
->data
, tmp
);
8403 /* Add the exit label. */
8404 tmp
= build1_v (LABEL_EXPR
, jump_label2
);
8405 gfc_add_expr_to_block (&fblock
, tmp
);
8407 return gfc_finish_block (&fblock
);
8411 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
8412 Do likewise, recursively if necessary, with the allocatable components of
8416 gfc_trans_deferred_array (gfc_symbol
* sym
, gfc_wrapped_block
* block
)
8422 stmtblock_t cleanup
;
8425 bool sym_has_alloc_comp
, has_finalizer
;
8427 sym_has_alloc_comp
= (sym
->ts
.type
== BT_DERIVED
8428 || sym
->ts
.type
== BT_CLASS
)
8429 && sym
->ts
.u
.derived
->attr
.alloc_comp
;
8430 has_finalizer
= sym
->ts
.type
== BT_CLASS
|| sym
->ts
.type
== BT_DERIVED
8431 ? gfc_is_finalizable (sym
->ts
.u
.derived
, NULL
) : false;
8433 /* Make sure the frontend gets these right. */
8434 gcc_assert (sym
->attr
.pointer
|| sym
->attr
.allocatable
|| sym_has_alloc_comp
8437 gfc_save_backend_locus (&loc
);
8438 gfc_set_backend_locus (&sym
->declared_at
);
8439 gfc_init_block (&init
);
8441 gcc_assert (TREE_CODE (sym
->backend_decl
) == VAR_DECL
8442 || TREE_CODE (sym
->backend_decl
) == PARM_DECL
);
8444 if (sym
->ts
.type
== BT_CHARACTER
8445 && !INTEGER_CST_P (sym
->ts
.u
.cl
->backend_decl
))
8447 gfc_conv_string_length (sym
->ts
.u
.cl
, NULL
, &init
);
8448 gfc_trans_vla_type_sizes (sym
, &init
);
8451 /* Dummy, use associated and result variables don't need anything special. */
8452 if (sym
->attr
.dummy
|| sym
->attr
.use_assoc
|| sym
->attr
.result
)
8454 gfc_add_init_cleanup (block
, gfc_finish_block (&init
), NULL_TREE
);
8455 gfc_restore_backend_locus (&loc
);
8459 descriptor
= sym
->backend_decl
;
8461 /* Although static, derived types with default initializers and
8462 allocatable components must not be nulled wholesale; instead they
8463 are treated component by component. */
8464 if (TREE_STATIC (descriptor
) && !sym_has_alloc_comp
&& !has_finalizer
)
8466 /* SAVEd variables are not freed on exit. */
8467 gfc_trans_static_array_pointer (sym
);
8469 gfc_add_init_cleanup (block
, gfc_finish_block (&init
), NULL_TREE
);
8470 gfc_restore_backend_locus (&loc
);
8474 /* Get the descriptor type. */
8475 type
= TREE_TYPE (sym
->backend_decl
);
8477 if ((sym_has_alloc_comp
|| (has_finalizer
&& sym
->ts
.type
!= BT_CLASS
))
8478 && !(sym
->attr
.pointer
|| sym
->attr
.allocatable
))
8481 && !(TREE_STATIC (sym
->backend_decl
) && sym
->attr
.is_main_program
))
8483 if (sym
->value
== NULL
8484 || !gfc_has_default_initializer (sym
->ts
.u
.derived
))
8486 rank
= sym
->as
? sym
->as
->rank
: 0;
8487 tmp
= gfc_nullify_alloc_comp (sym
->ts
.u
.derived
,
8489 gfc_add_expr_to_block (&init
, tmp
);
8492 gfc_init_default_dt (sym
, &init
, false);
8495 else if (!GFC_DESCRIPTOR_TYPE_P (type
))
8497 /* If the backend_decl is not a descriptor, we must have a pointer
8499 descriptor
= build_fold_indirect_ref_loc (input_location
,
8501 type
= TREE_TYPE (descriptor
);
8504 /* NULLIFY the data pointer. */
8505 if (GFC_DESCRIPTOR_TYPE_P (type
) && !sym
->attr
.save
)
8506 gfc_conv_descriptor_data_set (&init
, descriptor
, null_pointer_node
);
8508 gfc_restore_backend_locus (&loc
);
8509 gfc_init_block (&cleanup
);
8511 /* Allocatable arrays need to be freed when they go out of scope.
8512 The allocatable components of pointers must not be touched. */
8513 if (!sym
->attr
.allocatable
&& has_finalizer
&& sym
->ts
.type
!= BT_CLASS
8514 && !sym
->attr
.pointer
&& !sym
->attr
.artificial
&& !sym
->attr
.save
8515 && !sym
->ns
->proc_name
->attr
.is_main_program
)
8518 sym
->attr
.referenced
= 1;
8519 e
= gfc_lval_expr_from_sym (sym
);
8520 gfc_add_finalizer_call (&cleanup
, e
);
8523 else if ((!sym
->attr
.allocatable
|| !has_finalizer
)
8524 && sym_has_alloc_comp
&& !(sym
->attr
.function
|| sym
->attr
.result
)
8525 && !sym
->attr
.pointer
&& !sym
->attr
.save
8526 && !sym
->ns
->proc_name
->attr
.is_main_program
)
8529 rank
= sym
->as
? sym
->as
->rank
: 0;
8530 tmp
= gfc_deallocate_alloc_comp (sym
->ts
.u
.derived
, descriptor
, rank
);
8531 gfc_add_expr_to_block (&cleanup
, tmp
);
8534 if (sym
->attr
.allocatable
&& (sym
->attr
.dimension
|| sym
->attr
.codimension
)
8535 && !sym
->attr
.save
&& !sym
->attr
.result
8536 && !sym
->ns
->proc_name
->attr
.is_main_program
)
8539 e
= has_finalizer
? gfc_lval_expr_from_sym (sym
) : NULL
;
8540 tmp
= gfc_trans_dealloc_allocated (sym
->backend_decl
,
8541 sym
->attr
.codimension
, e
);
8544 gfc_add_expr_to_block (&cleanup
, tmp
);
8547 gfc_add_init_cleanup (block
, gfc_finish_block (&init
),
8548 gfc_finish_block (&cleanup
));
8551 /************ Expression Walking Functions ******************/
8553 /* Walk a variable reference.
8555 Possible extension - multiple component subscripts.
8556 x(:,:) = foo%a(:)%b(:)
8558 forall (i=..., j=...)
8559 x(i,j) = foo%a(j)%b(i)
8561 This adds a fair amount of complexity because you need to deal with more
8562 than one ref. Maybe handle in a similar manner to vector subscripts.
8563 Maybe not worth the effort. */
8567 gfc_walk_variable_expr (gfc_ss
* ss
, gfc_expr
* expr
)
8571 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
8572 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
8575 return gfc_walk_array_ref (ss
, expr
, ref
);
8580 gfc_walk_array_ref (gfc_ss
* ss
, gfc_expr
* expr
, gfc_ref
* ref
)
8586 for (; ref
; ref
= ref
->next
)
8588 if (ref
->type
== REF_SUBSTRING
)
8590 ss
= gfc_get_scalar_ss (ss
, ref
->u
.ss
.start
);
8591 ss
= gfc_get_scalar_ss (ss
, ref
->u
.ss
.end
);
8594 /* We're only interested in array sections from now on. */
8595 if (ref
->type
!= REF_ARRAY
)
8603 for (n
= ar
->dimen
- 1; n
>= 0; n
--)
8604 ss
= gfc_get_scalar_ss (ss
, ar
->start
[n
]);
8608 newss
= gfc_get_array_ss (ss
, expr
, ar
->as
->rank
, GFC_SS_SECTION
);
8609 newss
->info
->data
.array
.ref
= ref
;
8611 /* Make sure array is the same as array(:,:), this way
8612 we don't need to special case all the time. */
8613 ar
->dimen
= ar
->as
->rank
;
8614 for (n
= 0; n
< ar
->dimen
; n
++)
8616 ar
->dimen_type
[n
] = DIMEN_RANGE
;
8618 gcc_assert (ar
->start
[n
] == NULL
);
8619 gcc_assert (ar
->end
[n
] == NULL
);
8620 gcc_assert (ar
->stride
[n
] == NULL
);
8626 newss
= gfc_get_array_ss (ss
, expr
, 0, GFC_SS_SECTION
);
8627 newss
->info
->data
.array
.ref
= ref
;
8629 /* We add SS chains for all the subscripts in the section. */
8630 for (n
= 0; n
< ar
->dimen
; n
++)
8634 switch (ar
->dimen_type
[n
])
8637 /* Add SS for elemental (scalar) subscripts. */
8638 gcc_assert (ar
->start
[n
]);
8639 indexss
= gfc_get_scalar_ss (gfc_ss_terminator
, ar
->start
[n
]);
8640 indexss
->loop_chain
= gfc_ss_terminator
;
8641 newss
->info
->data
.array
.subscript
[n
] = indexss
;
8645 /* We don't add anything for sections, just remember this
8646 dimension for later. */
8647 newss
->dim
[newss
->dimen
] = n
;
8652 /* Create a GFC_SS_VECTOR index in which we can store
8653 the vector's descriptor. */
8654 indexss
= gfc_get_array_ss (gfc_ss_terminator
, ar
->start
[n
],
8656 indexss
->loop_chain
= gfc_ss_terminator
;
8657 newss
->info
->data
.array
.subscript
[n
] = indexss
;
8658 newss
->dim
[newss
->dimen
] = n
;
8663 /* We should know what sort of section it is by now. */
8667 /* We should have at least one non-elemental dimension,
8668 unless we are creating a descriptor for a (scalar) coarray. */
8669 gcc_assert (newss
->dimen
> 0
8670 || newss
->info
->data
.array
.ref
->u
.ar
.as
->corank
> 0);
8675 /* We should know what sort of section it is by now. */
8684 /* Walk an expression operator. If only one operand of a binary expression is
8685 scalar, we must also add the scalar term to the SS chain. */
8688 gfc_walk_op_expr (gfc_ss
* ss
, gfc_expr
* expr
)
8693 head
= gfc_walk_subexpr (ss
, expr
->value
.op
.op1
);
8694 if (expr
->value
.op
.op2
== NULL
)
8697 head2
= gfc_walk_subexpr (head
, expr
->value
.op
.op2
);
8699 /* All operands are scalar. Pass back and let the caller deal with it. */
8703 /* All operands require scalarization. */
8704 if (head
!= ss
&& (expr
->value
.op
.op2
== NULL
|| head2
!= head
))
8707 /* One of the operands needs scalarization, the other is scalar.
8708 Create a gfc_ss for the scalar expression. */
8711 /* First operand is scalar. We build the chain in reverse order, so
8712 add the scalar SS after the second operand. */
8714 while (head
&& head
->next
!= ss
)
8716 /* Check we haven't somehow broken the chain. */
8718 head
->next
= gfc_get_scalar_ss (ss
, expr
->value
.op
.op1
);
8720 else /* head2 == head */
8722 gcc_assert (head2
== head
);
8723 /* Second operand is scalar. */
8724 head2
= gfc_get_scalar_ss (head2
, expr
->value
.op
.op2
);
8731 /* Reverse a SS chain. */
8734 gfc_reverse_ss (gfc_ss
* ss
)
8739 gcc_assert (ss
!= NULL
);
8741 head
= gfc_ss_terminator
;
8742 while (ss
!= gfc_ss_terminator
)
8745 /* Check we didn't somehow break the chain. */
8746 gcc_assert (next
!= NULL
);
8756 /* Given an expression referring to a procedure, return the symbol of its
8757 interface. We can't get the procedure symbol directly as we have to handle
8758 the case of (deferred) type-bound procedures. */
8761 gfc_get_proc_ifc_for_expr (gfc_expr
*procedure_ref
)
8766 if (procedure_ref
== NULL
)
8769 /* Normal procedure case. */
8770 sym
= procedure_ref
->symtree
->n
.sym
;
8772 /* Typebound procedure case. */
8773 for (ref
= procedure_ref
->ref
; ref
; ref
= ref
->next
)
8775 if (ref
->type
== REF_COMPONENT
8776 && ref
->u
.c
.component
->attr
.proc_pointer
)
8777 sym
= ref
->u
.c
.component
->ts
.interface
;
8786 /* Walk the arguments of an elemental function.
8787 PROC_EXPR is used to check whether an argument is permitted to be absent. If
8788 it is NULL, we don't do the check and the argument is assumed to be present.
8792 gfc_walk_elemental_function_args (gfc_ss
* ss
, gfc_actual_arglist
*arg
,
8793 gfc_symbol
*proc_ifc
, gfc_ss_type type
)
8795 gfc_formal_arglist
*dummy_arg
;
8801 head
= gfc_ss_terminator
;
8805 dummy_arg
= gfc_sym_get_dummy_args (proc_ifc
);
8810 for (; arg
; arg
= arg
->next
)
8812 if (!arg
->expr
|| arg
->expr
->expr_type
== EXPR_NULL
)
8815 newss
= gfc_walk_subexpr (head
, arg
->expr
);
8818 /* Scalar argument. */
8819 gcc_assert (type
== GFC_SS_SCALAR
|| type
== GFC_SS_REFERENCE
);
8820 newss
= gfc_get_scalar_ss (head
, arg
->expr
);
8821 newss
->info
->type
= type
;
8827 if (dummy_arg
!= NULL
8828 && dummy_arg
->sym
->attr
.optional
8829 && arg
->expr
->expr_type
== EXPR_VARIABLE
8830 && (gfc_expr_attr (arg
->expr
).optional
8831 || gfc_expr_attr (arg
->expr
).allocatable
8832 || gfc_expr_attr (arg
->expr
).pointer
))
8833 newss
->info
->can_be_null_ref
= true;
8839 while (tail
->next
!= gfc_ss_terminator
)
8843 if (dummy_arg
!= NULL
)
8844 dummy_arg
= dummy_arg
->next
;
8849 /* If all the arguments are scalar we don't need the argument SS. */
8850 gfc_free_ss_chain (head
);
8855 /* Add it onto the existing chain. */
8861 /* Walk a function call. Scalar functions are passed back, and taken out of
8862 scalarization loops. For elemental functions we walk their arguments.
8863 The result of functions returning arrays is stored in a temporary outside
8864 the loop, so that the function is only called once. Hence we do not need
8865 to walk their arguments. */
8868 gfc_walk_function_expr (gfc_ss
* ss
, gfc_expr
* expr
)
8870 gfc_intrinsic_sym
*isym
;
8872 gfc_component
*comp
= NULL
;
8874 isym
= expr
->value
.function
.isym
;
8876 /* Handle intrinsic functions separately. */
8878 return gfc_walk_intrinsic_function (ss
, expr
, isym
);
8880 sym
= expr
->value
.function
.esym
;
8882 sym
= expr
->symtree
->n
.sym
;
8884 /* A function that returns arrays. */
8885 comp
= gfc_get_proc_ptr_comp (expr
);
8886 if ((!comp
&& gfc_return_by_reference (sym
) && sym
->result
->attr
.dimension
)
8887 || (comp
&& comp
->attr
.dimension
))
8888 return gfc_get_array_ss (ss
, expr
, expr
->rank
, GFC_SS_FUNCTION
);
8890 /* Walk the parameters of an elemental function. For now we always pass
8892 if (sym
->attr
.elemental
|| (comp
&& comp
->attr
.elemental
))
8893 return gfc_walk_elemental_function_args (ss
, expr
->value
.function
.actual
,
8894 gfc_get_proc_ifc_for_expr (expr
),
8897 /* Scalar functions are OK as these are evaluated outside the scalarization
8898 loop. Pass back and let the caller deal with it. */
8903 /* An array temporary is constructed for array constructors. */
8906 gfc_walk_array_constructor (gfc_ss
* ss
, gfc_expr
* expr
)
8908 return gfc_get_array_ss (ss
, expr
, expr
->rank
, GFC_SS_CONSTRUCTOR
);
8912 /* Walk an expression. Add walked expressions to the head of the SS chain.
8913 A wholly scalar expression will not be added. */
8916 gfc_walk_subexpr (gfc_ss
* ss
, gfc_expr
* expr
)
8920 switch (expr
->expr_type
)
8923 head
= gfc_walk_variable_expr (ss
, expr
);
8927 head
= gfc_walk_op_expr (ss
, expr
);
8931 head
= gfc_walk_function_expr (ss
, expr
);
8936 case EXPR_STRUCTURE
:
8937 /* Pass back and let the caller deal with it. */
8941 head
= gfc_walk_array_constructor (ss
, expr
);
8944 case EXPR_SUBSTRING
:
8945 /* Pass back and let the caller deal with it. */
8949 internal_error ("bad expression type during walk (%d)",
8956 /* Entry point for expression walking.
8957 A return value equal to the passed chain means this is
8958 a scalar expression. It is up to the caller to take whatever action is
8959 necessary to translate these. */
8962 gfc_walk_expr (gfc_expr
* expr
)
8966 res
= gfc_walk_subexpr (gfc_ss_terminator
, expr
);
8967 return gfc_reverse_ss (res
);