1 /* Expression translation
2 Copyright (C) 2002-2023 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-expr.cc-- generate GENERIC trees for gfc_expr. */
26 #include "coretypes.h"
31 #include "stringpool.h"
32 #include "diagnostic-core.h" /* For fatal_error. */
33 #include "fold-const.h"
34 #include "langhooks.h"
36 #include "constructor.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 #include "trans-stmt.h"
42 #include "dependency.h"
44 #include "tm.h" /* For CHAR_TYPE_SIZE. */
47 /* Calculate the number of characters in a string. */
50 gfc_get_character_len (tree type
)
54 gcc_assert (type
&& TREE_CODE (type
) == ARRAY_TYPE
55 && TYPE_STRING_FLAG (type
));
57 len
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
58 len
= (len
) ? (len
) : (integer_zero_node
);
59 return fold_convert (gfc_charlen_type_node
, len
);
64 /* Calculate the number of bytes in a string. */
67 gfc_get_character_len_in_bytes (tree type
)
71 gcc_assert (type
&& TREE_CODE (type
) == ARRAY_TYPE
72 && TYPE_STRING_FLAG (type
));
74 tmp
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
75 tmp
= (tmp
&& !integer_zerop (tmp
))
76 ? (fold_convert (gfc_charlen_type_node
, tmp
)) : (NULL_TREE
);
77 len
= gfc_get_character_len (type
);
78 if (tmp
&& len
&& !integer_zerop (len
))
79 len
= fold_build2_loc (input_location
, MULT_EXPR
,
80 gfc_charlen_type_node
, len
, tmp
);
85 /* Convert a scalar to an array descriptor. To be used for assumed-rank
89 get_scalar_to_descriptor_type (tree scalar
, symbol_attribute attr
)
91 enum gfc_array_kind akind
;
94 akind
= GFC_ARRAY_POINTER_CONT
;
95 else if (attr
.allocatable
)
96 akind
= GFC_ARRAY_ALLOCATABLE
;
98 akind
= GFC_ARRAY_ASSUMED_SHAPE_CONT
;
100 if (POINTER_TYPE_P (TREE_TYPE (scalar
)))
101 scalar
= TREE_TYPE (scalar
);
102 return gfc_get_array_type_bounds (TREE_TYPE (scalar
), 0, 0, NULL
, NULL
, 1,
103 akind
, !(attr
.pointer
|| attr
.target
));
107 gfc_conv_scalar_to_descriptor (gfc_se
*se
, tree scalar
, symbol_attribute attr
)
109 tree desc
, type
, etype
;
111 type
= get_scalar_to_descriptor_type (scalar
, attr
);
112 etype
= TREE_TYPE (scalar
);
113 desc
= gfc_create_var (type
, "desc");
114 DECL_ARTIFICIAL (desc
) = 1;
116 if (CONSTANT_CLASS_P (scalar
))
119 tmp
= gfc_create_var (TREE_TYPE (scalar
), "scalar");
120 gfc_add_modify (&se
->pre
, tmp
, scalar
);
123 if (!POINTER_TYPE_P (TREE_TYPE (scalar
)))
124 scalar
= gfc_build_addr_expr (NULL_TREE
, scalar
);
125 else if (TREE_TYPE (etype
) && TREE_CODE (TREE_TYPE (etype
)) == ARRAY_TYPE
)
126 etype
= TREE_TYPE (etype
);
127 gfc_add_modify (&se
->pre
, gfc_conv_descriptor_dtype (desc
),
128 gfc_get_dtype_rank_type (0, etype
));
129 gfc_conv_descriptor_data_set (&se
->pre
, desc
, scalar
);
130 gfc_conv_descriptor_span_set (&se
->pre
, desc
,
131 gfc_conv_descriptor_elem_len (desc
));
133 /* Copy pointer address back - but only if it could have changed and
134 if the actual argument is a pointer and not, e.g., NULL(). */
135 if ((attr
.pointer
|| attr
.allocatable
) && attr
.intent
!= INTENT_IN
)
136 gfc_add_modify (&se
->post
, scalar
,
137 fold_convert (TREE_TYPE (scalar
),
138 gfc_conv_descriptor_data_get (desc
)));
143 /* Get the coarray token from the ultimate array or component ref.
144 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
147 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se
*outerse
, gfc_expr
*expr
)
149 gfc_symbol
*sym
= expr
->symtree
->n
.sym
;
150 bool is_coarray
= sym
->attr
.codimension
;
151 gfc_expr
*caf_expr
= gfc_copy_expr (expr
);
152 gfc_ref
*ref
= caf_expr
->ref
, *last_caf_ref
= NULL
;
156 if (ref
->type
== REF_COMPONENT
157 && (ref
->u
.c
.component
->attr
.allocatable
158 || ref
->u
.c
.component
->attr
.pointer
)
159 && (is_coarray
|| ref
->u
.c
.component
->attr
.codimension
))
164 if (last_caf_ref
== NULL
)
167 tree comp
= last_caf_ref
->u
.c
.component
->caf_token
, caf
;
169 bool comp_ref
= !last_caf_ref
->u
.c
.component
->attr
.dimension
;
170 if (comp
== NULL_TREE
&& comp_ref
)
172 gfc_init_se (&se
, outerse
);
173 gfc_free_ref_list (last_caf_ref
->next
);
174 last_caf_ref
->next
= NULL
;
175 caf_expr
->rank
= comp_ref
? 0 : last_caf_ref
->u
.c
.component
->as
->rank
;
176 se
.want_pointer
= comp_ref
;
177 gfc_conv_expr (&se
, caf_expr
);
178 gfc_add_block_to_block (&outerse
->pre
, &se
.pre
);
180 if (TREE_CODE (se
.expr
) == COMPONENT_REF
&& comp_ref
)
181 se
.expr
= TREE_OPERAND (se
.expr
, 0);
182 gfc_free_expr (caf_expr
);
185 caf
= fold_build3_loc (input_location
, COMPONENT_REF
,
186 TREE_TYPE (comp
), se
.expr
, comp
, NULL_TREE
);
188 caf
= gfc_conv_descriptor_token (se
.expr
);
189 return gfc_build_addr_expr (NULL_TREE
, caf
);
193 /* This is the seed for an eventual trans-class.c
195 The following parameters should not be used directly since they might
196 in future implementations. Use the corresponding APIs. */
197 #define CLASS_DATA_FIELD 0
198 #define CLASS_VPTR_FIELD 1
199 #define CLASS_LEN_FIELD 2
200 #define VTABLE_HASH_FIELD 0
201 #define VTABLE_SIZE_FIELD 1
202 #define VTABLE_EXTENDS_FIELD 2
203 #define VTABLE_DEF_INIT_FIELD 3
204 #define VTABLE_COPY_FIELD 4
205 #define VTABLE_FINAL_FIELD 5
206 #define VTABLE_DEALLOCATE_FIELD 6
210 gfc_class_set_static_fields (tree decl
, tree vptr
, tree data
)
214 vec
<constructor_elt
, va_gc
> *init
= NULL
;
216 field
= TYPE_FIELDS (TREE_TYPE (decl
));
217 tmp
= gfc_advance_chain (field
, CLASS_DATA_FIELD
);
218 CONSTRUCTOR_APPEND_ELT (init
, tmp
, data
);
220 tmp
= gfc_advance_chain (field
, CLASS_VPTR_FIELD
);
221 CONSTRUCTOR_APPEND_ELT (init
, tmp
, vptr
);
223 return build_constructor (TREE_TYPE (decl
), init
);
228 gfc_class_data_get (tree decl
)
231 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
232 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
233 data
= gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl
)),
235 return fold_build3_loc (input_location
, COMPONENT_REF
,
236 TREE_TYPE (data
), decl
, data
,
242 gfc_class_vptr_get (tree decl
)
245 /* For class arrays decl may be a temporary descriptor handle, the vptr is
246 then available through the saved descriptor. */
247 if (VAR_P (decl
) && DECL_LANG_SPECIFIC (decl
)
248 && GFC_DECL_SAVED_DESCRIPTOR (decl
))
249 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
250 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
251 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
252 vptr
= gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl
)),
254 return fold_build3_loc (input_location
, COMPONENT_REF
,
255 TREE_TYPE (vptr
), decl
, vptr
,
261 gfc_class_len_get (tree decl
)
264 /* For class arrays decl may be a temporary descriptor handle, the len is
265 then available through the saved descriptor. */
266 if (VAR_P (decl
) && DECL_LANG_SPECIFIC (decl
)
267 && GFC_DECL_SAVED_DESCRIPTOR (decl
))
268 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
269 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
270 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
271 len
= gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl
)),
273 return fold_build3_loc (input_location
, COMPONENT_REF
,
274 TREE_TYPE (len
), decl
, len
,
279 /* Try to get the _len component of a class. When the class is not unlimited
280 poly, i.e. no _len field exists, then return a zero node. */
283 gfc_class_len_or_zero_get (tree decl
)
286 /* For class arrays decl may be a temporary descriptor handle, the vptr is
287 then available through the saved descriptor. */
288 if (VAR_P (decl
) && DECL_LANG_SPECIFIC (decl
)
289 && GFC_DECL_SAVED_DESCRIPTOR (decl
))
290 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
291 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
292 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
293 len
= gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl
)),
295 return len
!= NULL_TREE
? fold_build3_loc (input_location
, COMPONENT_REF
,
296 TREE_TYPE (len
), decl
, len
,
298 : build_zero_cst (gfc_charlen_type_node
);
303 gfc_resize_class_size_with_len (stmtblock_t
* block
, tree class_expr
, tree size
)
309 tmp
= gfc_class_len_or_zero_get (class_expr
);
311 /* Include the len value in the element size if present. */
312 if (!integer_zerop (tmp
))
314 type
= TREE_TYPE (size
);
317 size
= gfc_evaluate_now (size
, block
);
318 tmp
= gfc_evaluate_now (fold_convert (type
, tmp
), block
);
320 tmp2
= fold_build2_loc (input_location
, MULT_EXPR
,
322 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
323 logical_type_node
, tmp
,
324 build_zero_cst (type
));
325 size
= fold_build3_loc (input_location
, COND_EXPR
,
326 type
, tmp
, tmp2
, size
);
332 size
= gfc_evaluate_now (size
, block
);
338 /* Get the specified FIELD from the VPTR. */
341 vptr_field_get (tree vptr
, int fieldno
)
344 vptr
= build_fold_indirect_ref_loc (input_location
, vptr
);
345 field
= gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr
)),
347 field
= fold_build3_loc (input_location
, COMPONENT_REF
,
348 TREE_TYPE (field
), vptr
, field
,
355 /* Get the field from the class' vptr. */
358 class_vtab_field_get (tree decl
, int fieldno
)
361 vptr
= gfc_class_vptr_get (decl
);
362 return vptr_field_get (vptr
, fieldno
);
366 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
368 #define VTAB_GET_FIELD_GEN(name, field) tree \
369 gfc_class_vtab_## name ##_get (tree cl) \
371 return class_vtab_field_get (cl, field); \
375 gfc_vptr_## name ##_get (tree vptr) \
377 return vptr_field_get (vptr, field); \
380 VTAB_GET_FIELD_GEN (hash
, VTABLE_HASH_FIELD
)
381 VTAB_GET_FIELD_GEN (extends
, VTABLE_EXTENDS_FIELD
)
382 VTAB_GET_FIELD_GEN (def_init
, VTABLE_DEF_INIT_FIELD
)
383 VTAB_GET_FIELD_GEN (copy
, VTABLE_COPY_FIELD
)
384 VTAB_GET_FIELD_GEN (final
, VTABLE_FINAL_FIELD
)
385 VTAB_GET_FIELD_GEN (deallocate
, VTABLE_DEALLOCATE_FIELD
)
386 #undef VTAB_GET_FIELD_GEN
388 /* The size field is returned as an array index type. Therefore treat
389 it and only it specially. */
392 gfc_class_vtab_size_get (tree cl
)
395 size
= class_vtab_field_get (cl
, VTABLE_SIZE_FIELD
);
396 /* Always return size as an array index type. */
397 size
= fold_convert (gfc_array_index_type
, size
);
403 gfc_vptr_size_get (tree vptr
)
406 size
= vptr_field_get (vptr
, VTABLE_SIZE_FIELD
);
407 /* Always return size as an array index type. */
408 size
= fold_convert (gfc_array_index_type
, size
);
414 #undef CLASS_DATA_FIELD
415 #undef CLASS_VPTR_FIELD
416 #undef CLASS_LEN_FIELD
417 #undef VTABLE_HASH_FIELD
418 #undef VTABLE_SIZE_FIELD
419 #undef VTABLE_EXTENDS_FIELD
420 #undef VTABLE_DEF_INIT_FIELD
421 #undef VTABLE_COPY_FIELD
422 #undef VTABLE_FINAL_FIELD
425 /* IF ts is null (default), search for the last _class ref in the chain
426 of references of the expression and cut the chain there. Although
427 this routine is similiar to class.cc:gfc_add_component_ref (), there
428 is a significant difference: gfc_add_component_ref () concentrates
429 on an array ref that is the last ref in the chain and is oblivious
430 to the kind of refs following.
431 ELSE IF ts is non-null the cut is at the class entity or component
432 that is followed by an array reference, which is not an element.
433 These calls come from trans-array.cc:build_class_array_ref, which
434 handles scalarized class array references.*/
437 gfc_find_and_cut_at_last_class_ref (gfc_expr
*e
, bool is_mold
,
441 gfc_ref
*ref
, *class_ref
, *tail
= NULL
, *array_ref
;
443 /* Find the last class reference. */
450 && e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
451 *ts
= &e
->symtree
->n
.sym
->ts
;
456 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
460 if (ref
->type
== REF_COMPONENT
461 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
462 && ref
->next
&& ref
->next
->type
== REF_COMPONENT
463 && !strcmp (ref
->next
->u
.c
.component
->name
, "_data")
465 && ref
->next
->next
->type
== REF_ARRAY
466 && ref
->next
->next
->u
.ar
.type
!= AR_ELEMENT
)
468 *ts
= &ref
->u
.c
.component
->ts
;
473 if (ref
->next
== NULL
)
478 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
481 if (ref
->type
== REF_COMPONENT
482 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
)
484 /* Component to the right of a part reference with nonzero
485 rank must not have the ALLOCATABLE attribute. If attempts
486 are made to reference such a component reference, an error
487 results followed by an ICE. */
489 && CLASS_DATA (ref
->u
.c
.component
)->attr
.allocatable
)
496 if (ts
&& *ts
== NULL
)
499 /* Remove and store all subsequent references after the
503 tail
= class_ref
->next
;
504 class_ref
->next
= NULL
;
506 else if (e
->symtree
&& e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
513 base_expr
= gfc_expr_to_initialize (e
);
515 base_expr
= gfc_copy_expr (e
);
517 /* Restore the original tail expression. */
520 gfc_free_ref_list (class_ref
->next
);
521 class_ref
->next
= tail
;
523 else if (e
->symtree
&& e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
525 gfc_free_ref_list (e
->ref
);
532 /* Reset the vptr to the declared type, e.g. after deallocation. */
535 gfc_reset_vptr (stmtblock_t
*block
, gfc_expr
*e
)
542 /* Evaluate the expression and obtain the vptr from it. */
543 gfc_init_se (&se
, NULL
);
545 gfc_conv_expr_descriptor (&se
, e
);
547 gfc_conv_expr (&se
, e
);
548 gfc_add_block_to_block (block
, &se
.pre
);
549 vptr
= gfc_get_vptr_from_expr (se
.expr
);
551 /* If a vptr is not found, we can do nothing more. */
552 if (vptr
== NULL_TREE
)
555 if (UNLIMITED_POLY (e
))
556 gfc_add_modify (block
, vptr
, build_int_cst (TREE_TYPE (vptr
), 0));
559 /* Return the vptr to the address of the declared type. */
560 vtab
= gfc_find_derived_vtab (e
->ts
.u
.derived
);
561 vtable
= vtab
->backend_decl
;
562 if (vtable
== NULL_TREE
)
563 vtable
= gfc_get_symbol_decl (vtab
);
564 vtable
= gfc_build_addr_expr (NULL
, vtable
);
565 vtable
= fold_convert (TREE_TYPE (vptr
), vtable
);
566 gfc_add_modify (block
, vptr
, vtable
);
571 /* Reset the len for unlimited polymorphic objects. */
574 gfc_reset_len (stmtblock_t
*block
, gfc_expr
*expr
)
578 e
= gfc_find_and_cut_at_last_class_ref (expr
);
581 gfc_add_len_component (e
);
582 gfc_init_se (&se_len
, NULL
);
583 gfc_conv_expr (&se_len
, e
);
584 gfc_add_modify (block
, se_len
.expr
,
585 fold_convert (TREE_TYPE (se_len
.expr
), integer_zero_node
));
590 /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
591 reference is found. Note that it is up to the caller to avoid using this
592 for expressions other than variables. */
595 gfc_get_class_from_gfc_expr (gfc_expr
*e
)
597 gfc_expr
*class_expr
;
599 class_expr
= gfc_find_and_cut_at_last_class_ref (e
);
600 if (class_expr
== NULL
)
602 gfc_init_se (&cse
, NULL
);
603 gfc_conv_expr (&cse
, class_expr
);
604 gfc_free_expr (class_expr
);
609 /* Obtain the last class reference in an expression.
610 Return NULL_TREE if no class reference is found. */
613 gfc_get_class_from_expr (tree expr
)
618 for (tmp
= expr
; tmp
; tmp
= TREE_OPERAND (tmp
, 0))
620 if (CONSTANT_CLASS_P (tmp
))
623 type
= TREE_TYPE (tmp
);
626 if (GFC_CLASS_TYPE_P (type
))
628 if (type
!= TYPE_CANONICAL (type
))
629 type
= TYPE_CANONICAL (type
);
633 if (VAR_P (tmp
) || TREE_CODE (tmp
) == PARM_DECL
)
637 if (POINTER_TYPE_P (TREE_TYPE (tmp
)))
638 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
640 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp
)))
647 /* Obtain the vptr of the last class reference in an expression.
648 Return NULL_TREE if no class reference is found. */
651 gfc_get_vptr_from_expr (tree expr
)
655 tmp
= gfc_get_class_from_expr (expr
);
657 if (tmp
!= NULL_TREE
)
658 return gfc_class_vptr_get (tmp
);
665 class_array_data_assign (stmtblock_t
*block
, tree lhs_desc
, tree rhs_desc
,
668 tree tmp
, tmp2
, type
;
670 gfc_conv_descriptor_data_set (block
, lhs_desc
,
671 gfc_conv_descriptor_data_get (rhs_desc
));
672 gfc_conv_descriptor_offset_set (block
, lhs_desc
,
673 gfc_conv_descriptor_offset_get (rhs_desc
));
675 gfc_add_modify (block
, gfc_conv_descriptor_dtype (lhs_desc
),
676 gfc_conv_descriptor_dtype (rhs_desc
));
678 /* Assign the dimension as range-ref. */
679 tmp
= gfc_get_descriptor_dimension (lhs_desc
);
680 tmp2
= gfc_get_descriptor_dimension (rhs_desc
);
682 type
= lhs_type
? TREE_TYPE (tmp
) : TREE_TYPE (tmp2
);
683 tmp
= build4_loc (input_location
, ARRAY_RANGE_REF
, type
, tmp
,
684 gfc_index_zero_node
, NULL_TREE
, NULL_TREE
);
685 tmp2
= build4_loc (input_location
, ARRAY_RANGE_REF
, type
, tmp2
,
686 gfc_index_zero_node
, NULL_TREE
, NULL_TREE
);
687 gfc_add_modify (block
, tmp
, tmp2
);
691 /* Takes a derived type expression and returns the address of a temporary
692 class object of the 'declared' type. If vptr is not NULL, this is
693 used for the temporary class object.
694 optional_alloc_ptr is false when the dummy is neither allocatable
695 nor a pointer; that's only relevant for the optional handling.
696 The optional argument 'derived_array' is used to preserve the parmse
697 expression for deallocation of allocatable components. Assumed rank
698 formal arguments made this necessary. */
700 gfc_conv_derived_to_class (gfc_se
*parmse
, gfc_expr
*e
,
701 gfc_typespec class_ts
, tree vptr
, bool optional
,
702 bool optional_alloc_ptr
,
706 tree cond_optional
= NULL_TREE
;
713 /* The derived type needs to be converted to a temporary
715 tmp
= gfc_typenode_for_spec (&class_ts
);
716 var
= gfc_create_var (tmp
, "class");
719 ctree
= gfc_class_vptr_get (var
);
721 if (vptr
!= NULL_TREE
)
723 /* Use the dynamic vptr. */
728 /* In this case the vtab corresponds to the derived type and the
729 vptr must point to it. */
730 vtab
= gfc_find_derived_vtab (e
->ts
.u
.derived
);
732 tmp
= gfc_build_addr_expr (NULL_TREE
, gfc_get_symbol_decl (vtab
));
734 gfc_add_modify (&parmse
->pre
, ctree
,
735 fold_convert (TREE_TYPE (ctree
), tmp
));
737 /* Now set the data field. */
738 ctree
= gfc_class_data_get (var
);
741 cond_optional
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
743 if (parmse
->expr
&& POINTER_TYPE_P (TREE_TYPE (parmse
->expr
)))
745 /* If there is a ready made pointer to a derived type, use it
746 rather than evaluating the expression again. */
747 tmp
= fold_convert (TREE_TYPE (ctree
), parmse
->expr
);
748 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
750 else if (parmse
->ss
&& parmse
->ss
->info
&& parmse
->ss
->info
->useflags
)
752 /* For an array reference in an elemental procedure call we need
753 to retain the ss to provide the scalarized array reference. */
754 gfc_conv_expr_reference (parmse
, e
);
755 tmp
= fold_convert (TREE_TYPE (ctree
), parmse
->expr
);
757 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (tmp
),
759 fold_convert (TREE_TYPE (tmp
), null_pointer_node
));
760 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
764 ss
= gfc_walk_expr (e
);
765 if (ss
== gfc_ss_terminator
)
768 gfc_conv_expr_reference (parmse
, e
);
770 /* Scalar to an assumed-rank array. */
771 if (class_ts
.u
.derived
->components
->as
)
774 type
= get_scalar_to_descriptor_type (parmse
->expr
,
776 gfc_add_modify (&parmse
->pre
, gfc_conv_descriptor_dtype (ctree
),
777 gfc_get_dtype (type
));
779 parmse
->expr
= build3_loc (input_location
, COND_EXPR
,
780 TREE_TYPE (parmse
->expr
),
781 cond_optional
, parmse
->expr
,
782 fold_convert (TREE_TYPE (parmse
->expr
),
784 gfc_conv_descriptor_data_set (&parmse
->pre
, ctree
, parmse
->expr
);
788 tmp
= fold_convert (TREE_TYPE (ctree
), parmse
->expr
);
790 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (tmp
),
792 fold_convert (TREE_TYPE (tmp
),
794 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
800 gfc_init_block (&block
);
804 parmse
->use_offset
= 1;
805 gfc_conv_expr_descriptor (parmse
, e
);
807 /* Detect any array references with vector subscripts. */
808 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
809 if (ref
->type
== REF_ARRAY
810 && ref
->u
.ar
.type
!= AR_ELEMENT
811 && ref
->u
.ar
.type
!= AR_FULL
)
813 for (dim
= 0; dim
< ref
->u
.ar
.dimen
; dim
++)
814 if (ref
->u
.ar
.dimen_type
[dim
] == DIMEN_VECTOR
)
816 if (dim
< ref
->u
.ar
.dimen
)
820 /* Array references with vector subscripts and non-variable expressions
821 need be converted to a one-based descriptor. */
822 if (ref
|| e
->expr_type
!= EXPR_VARIABLE
)
824 for (dim
= 0; dim
< e
->rank
; ++dim
)
825 gfc_conv_shift_descriptor_lbound (&block
, parmse
->expr
, dim
,
829 if (e
->rank
!= class_ts
.u
.derived
->components
->as
->rank
)
831 gcc_assert (class_ts
.u
.derived
->components
->as
->type
834 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse
->expr
)))
836 *derived_array
= gfc_create_var (TREE_TYPE (parmse
->expr
),
838 gfc_add_modify (&block
, *derived_array
, parmse
->expr
);
840 class_array_data_assign (&block
, ctree
, parmse
->expr
, false);
844 if (gfc_expr_attr (e
).codimension
)
845 parmse
->expr
= fold_build1_loc (input_location
,
849 gfc_add_modify (&block
, ctree
, parmse
->expr
);
854 tmp
= gfc_finish_block (&block
);
856 gfc_init_block (&block
);
857 gfc_conv_descriptor_data_set (&block
, ctree
, null_pointer_node
);
858 if (derived_array
&& *derived_array
!= NULL_TREE
)
859 gfc_conv_descriptor_data_set (&block
, *derived_array
,
862 tmp
= build3_v (COND_EXPR
, cond_optional
, tmp
,
863 gfc_finish_block (&block
));
864 gfc_add_expr_to_block (&parmse
->pre
, tmp
);
867 gfc_add_block_to_block (&parmse
->pre
, &block
);
871 if (class_ts
.u
.derived
->components
->ts
.type
== BT_DERIVED
872 && class_ts
.u
.derived
->components
->ts
.u
.derived
873 ->attr
.unlimited_polymorphic
)
875 /* Take care about initializing the _len component correctly. */
876 ctree
= gfc_class_len_get (var
);
877 if (UNLIMITED_POLY (e
))
882 len
= gfc_find_and_cut_at_last_class_ref (e
);
883 gfc_add_len_component (len
);
884 gfc_init_se (&se
, NULL
);
885 gfc_conv_expr (&se
, len
);
887 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (se
.expr
),
888 cond_optional
, se
.expr
,
889 fold_convert (TREE_TYPE (se
.expr
),
896 tmp
= integer_zero_node
;
897 gfc_add_modify (&parmse
->pre
, ctree
, fold_convert (TREE_TYPE (ctree
),
900 /* Pass the address of the class object. */
901 parmse
->expr
= gfc_build_addr_expr (NULL_TREE
, var
);
903 if (optional
&& optional_alloc_ptr
)
904 parmse
->expr
= build3_loc (input_location
, COND_EXPR
,
905 TREE_TYPE (parmse
->expr
),
906 cond_optional
, parmse
->expr
,
907 fold_convert (TREE_TYPE (parmse
->expr
),
912 /* Create a new class container, which is required as scalar coarrays
913 have an array descriptor while normal scalars haven't. Optionally,
914 NULL pointer checks are added if the argument is OPTIONAL. */
917 class_scalar_coarray_to_class (gfc_se
*parmse
, gfc_expr
*e
,
918 gfc_typespec class_ts
, bool optional
)
920 tree var
, ctree
, tmp
;
925 gfc_init_block (&block
);
928 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
930 if (ref
->type
== REF_COMPONENT
931 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
)
935 if (class_ref
== NULL
936 && e
->symtree
&& e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
937 tmp
= e
->symtree
->n
.sym
->backend_decl
;
940 /* Remove everything after the last class reference, convert the
941 expression and then recover its tailend once more. */
943 ref
= class_ref
->next
;
944 class_ref
->next
= NULL
;
945 gfc_init_se (&tmpse
, NULL
);
946 gfc_conv_expr (&tmpse
, e
);
947 class_ref
->next
= ref
;
951 var
= gfc_typenode_for_spec (&class_ts
);
952 var
= gfc_create_var (var
, "class");
954 ctree
= gfc_class_vptr_get (var
);
955 gfc_add_modify (&block
, ctree
,
956 fold_convert (TREE_TYPE (ctree
), gfc_class_vptr_get (tmp
)));
958 ctree
= gfc_class_data_get (var
);
959 tmp
= gfc_conv_descriptor_data_get (gfc_class_data_get (tmp
));
960 gfc_add_modify (&block
, ctree
, fold_convert (TREE_TYPE (ctree
), tmp
));
962 /* Pass the address of the class object. */
963 parmse
->expr
= gfc_build_addr_expr (NULL_TREE
, var
);
967 tree cond
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
970 tmp
= gfc_finish_block (&block
);
972 gfc_init_block (&block
);
973 tmp2
= gfc_class_data_get (var
);
974 gfc_add_modify (&block
, tmp2
, fold_convert (TREE_TYPE (tmp2
),
976 tmp2
= gfc_finish_block (&block
);
978 tmp
= build3_loc (input_location
, COND_EXPR
, void_type_node
,
980 gfc_add_expr_to_block (&parmse
->pre
, tmp
);
983 gfc_add_block_to_block (&parmse
->pre
, &block
);
987 /* Takes an intrinsic type expression and returns the address of a temporary
988 class object of the 'declared' type. */
990 gfc_conv_intrinsic_to_class (gfc_se
*parmse
, gfc_expr
*e
,
991 gfc_typespec class_ts
)
1000 /* The intrinsic type needs to be converted to a temporary
1002 tmp
= gfc_typenode_for_spec (&class_ts
);
1003 var
= gfc_create_var (tmp
, "class");
1006 ctree
= gfc_class_vptr_get (var
);
1008 vtab
= gfc_find_vtab (&e
->ts
);
1010 tmp
= gfc_build_addr_expr (NULL_TREE
, gfc_get_symbol_decl (vtab
));
1011 gfc_add_modify (&parmse
->pre
, ctree
,
1012 fold_convert (TREE_TYPE (ctree
), tmp
));
1014 /* Now set the data field. */
1015 ctree
= gfc_class_data_get (var
);
1016 if (parmse
->ss
&& parmse
->ss
->info
->useflags
)
1018 /* For an array reference in an elemental procedure call we need
1019 to retain the ss to provide the scalarized array reference. */
1020 gfc_conv_expr_reference (parmse
, e
);
1021 tmp
= fold_convert (TREE_TYPE (ctree
), parmse
->expr
);
1022 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
1026 ss
= gfc_walk_expr (e
);
1027 if (ss
== gfc_ss_terminator
)
1030 gfc_conv_expr_reference (parmse
, e
);
1031 if (class_ts
.u
.derived
->components
->as
1032 && class_ts
.u
.derived
->components
->as
->type
== AS_ASSUMED_RANK
)
1034 tmp
= gfc_conv_scalar_to_descriptor (parmse
, parmse
->expr
,
1036 tmp
= fold_build1_loc (input_location
, VIEW_CONVERT_EXPR
,
1037 TREE_TYPE (ctree
), tmp
);
1040 tmp
= fold_convert (TREE_TYPE (ctree
), parmse
->expr
);
1041 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
1046 parmse
->use_offset
= 1;
1047 gfc_conv_expr_descriptor (parmse
, e
);
1049 /* Array references with vector subscripts and non-variable expressions
1050 need be converted to a one-based descriptor. */
1051 if (e
->expr_type
!= EXPR_VARIABLE
)
1053 for (dim
= 0; dim
< e
->rank
; ++dim
)
1054 gfc_conv_shift_descriptor_lbound (&parmse
->pre
, parmse
->expr
,
1055 dim
, gfc_index_one_node
);
1058 if (class_ts
.u
.derived
->components
->as
->rank
!= e
->rank
)
1060 tmp
= fold_build1_loc (input_location
, VIEW_CONVERT_EXPR
,
1061 TREE_TYPE (ctree
), parmse
->expr
);
1062 gfc_add_modify (&parmse
->pre
, ctree
, tmp
);
1065 gfc_add_modify (&parmse
->pre
, ctree
, parmse
->expr
);
1069 gcc_assert (class_ts
.type
== BT_CLASS
);
1070 if (class_ts
.u
.derived
->components
->ts
.type
== BT_DERIVED
1071 && class_ts
.u
.derived
->components
->ts
.u
.derived
1072 ->attr
.unlimited_polymorphic
)
1074 ctree
= gfc_class_len_get (var
);
1075 /* When the actual arg is a char array, then set the _len component of the
1076 unlimited polymorphic entity to the length of the string. */
1077 if (e
->ts
.type
== BT_CHARACTER
)
1079 /* Start with parmse->string_length because this seems to be set to a
1080 correct value more often. */
1081 if (parmse
->string_length
)
1082 tmp
= parmse
->string_length
;
1083 /* When the string_length is not yet set, then try the backend_decl of
1085 else if (e
->ts
.u
.cl
->backend_decl
)
1086 tmp
= e
->ts
.u
.cl
->backend_decl
;
1087 /* If both of the above approaches fail, then try to generate an
1088 expression from the input, which is only feasible currently, when the
1089 expression can be evaluated to a constant one. */
1092 /* Try to simplify the expression. */
1093 gfc_simplify_expr (e
, 0);
1094 if (e
->expr_type
== EXPR_CONSTANT
&& !e
->ts
.u
.cl
->resolved
)
1096 /* Amazingly all data is present to compute the length of a
1097 constant string, but the expression is not yet there. */
1098 e
->ts
.u
.cl
->length
= gfc_get_constant_expr (BT_INTEGER
,
1099 gfc_charlen_int_kind
,
1101 mpz_set_ui (e
->ts
.u
.cl
->length
->value
.integer
,
1102 e
->value
.character
.length
);
1103 gfc_conv_const_charlen (e
->ts
.u
.cl
);
1104 e
->ts
.u
.cl
->resolved
= 1;
1105 tmp
= e
->ts
.u
.cl
->backend_decl
;
1109 gfc_error ("Cannot compute the length of the char array "
1110 "at %L.", &e
->where
);
1115 tmp
= integer_zero_node
;
1117 gfc_add_modify (&parmse
->pre
, ctree
, fold_convert (TREE_TYPE (ctree
), tmp
));
1119 else if (class_ts
.type
== BT_CLASS
1120 && class_ts
.u
.derived
->components
1121 && class_ts
.u
.derived
->components
->ts
.u
1122 .derived
->attr
.unlimited_polymorphic
)
1124 ctree
= gfc_class_len_get (var
);
1125 gfc_add_modify (&parmse
->pre
, ctree
,
1126 fold_convert (TREE_TYPE (ctree
),
1127 integer_zero_node
));
1129 /* Pass the address of the class object. */
1130 parmse
->expr
= gfc_build_addr_expr (NULL_TREE
, var
);
1134 /* Takes a scalarized class array expression and returns the
1135 address of a temporary scalar class object of the 'declared'
1137 OOP-TODO: This could be improved by adding code that branched on
1138 the dynamic type being the same as the declared type. In this case
1139 the original class expression can be passed directly.
1140 optional_alloc_ptr is false when the dummy is neither allocatable
1141 nor a pointer; that's relevant for the optional handling.
1142 Set copyback to true if class container's _data and _vtab pointers
1143 might get modified. */
1146 gfc_conv_class_to_class (gfc_se
*parmse
, gfc_expr
*e
, gfc_typespec class_ts
,
1147 bool elemental
, bool copyback
, bool optional
,
1148 bool optional_alloc_ptr
)
1154 tree cond
= NULL_TREE
;
1155 tree slen
= NULL_TREE
;
1159 bool full_array
= false;
1161 gfc_init_block (&block
);
1164 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
1166 if (ref
->type
== REF_COMPONENT
1167 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
)
1170 if (ref
->next
== NULL
)
1174 if ((ref
== NULL
|| class_ref
== ref
)
1175 && !(gfc_is_class_array_function (e
) && parmse
->class_vptr
!= NULL_TREE
)
1176 && (!class_ts
.u
.derived
->components
->as
1177 || class_ts
.u
.derived
->components
->as
->rank
!= -1))
1180 /* Test for FULL_ARRAY. */
1182 && ((gfc_expr_attr (e
).codimension
&& gfc_expr_attr (e
).dimension
)
1183 || (class_ts
.u
.derived
->components
->as
1184 && class_ts
.u
.derived
->components
->as
->type
== AS_ASSUMED_RANK
)))
1187 gfc_is_class_array_ref (e
, &full_array
);
1189 /* The derived type needs to be converted to a temporary
1191 tmp
= gfc_typenode_for_spec (&class_ts
);
1192 var
= gfc_create_var (tmp
, "class");
1195 ctree
= gfc_class_data_get (var
);
1196 if (class_ts
.u
.derived
->components
->as
1197 && e
->rank
!= class_ts
.u
.derived
->components
->as
->rank
)
1201 tree type
= get_scalar_to_descriptor_type (parmse
->expr
,
1203 gfc_add_modify (&block
, gfc_conv_descriptor_dtype (ctree
),
1204 gfc_get_dtype (type
));
1206 tmp
= gfc_class_data_get (parmse
->expr
);
1207 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
1208 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
1210 gfc_conv_descriptor_data_set (&block
, ctree
, tmp
);
1213 class_array_data_assign (&block
, ctree
, parmse
->expr
, false);
1217 if (TREE_TYPE (parmse
->expr
) != TREE_TYPE (ctree
))
1218 parmse
->expr
= fold_build1_loc (input_location
, VIEW_CONVERT_EXPR
,
1219 TREE_TYPE (ctree
), parmse
->expr
);
1220 gfc_add_modify (&block
, ctree
, parmse
->expr
);
1223 /* Return the data component, except in the case of scalarized array
1224 references, where nullification of the cannot occur and so there
1226 if (!elemental
&& full_array
&& copyback
)
1228 if (class_ts
.u
.derived
->components
->as
1229 && e
->rank
!= class_ts
.u
.derived
->components
->as
->rank
)
1233 tmp
= gfc_class_data_get (parmse
->expr
);
1234 gfc_add_modify (&parmse
->post
, tmp
,
1235 fold_convert (TREE_TYPE (tmp
),
1236 gfc_conv_descriptor_data_get (ctree
)));
1239 class_array_data_assign (&parmse
->post
, parmse
->expr
, ctree
, true);
1242 gfc_add_modify (&parmse
->post
, parmse
->expr
, ctree
);
1246 ctree
= gfc_class_vptr_get (var
);
1248 /* The vptr is the second field of the actual argument.
1249 First we have to find the corresponding class reference. */
1252 if (gfc_is_class_array_function (e
)
1253 && parmse
->class_vptr
!= NULL_TREE
)
1254 tmp
= parmse
->class_vptr
;
1255 else if (class_ref
== NULL
1256 && e
->symtree
&& e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
1258 tmp
= e
->symtree
->n
.sym
->backend_decl
;
1260 if (TREE_CODE (tmp
) == FUNCTION_DECL
)
1261 tmp
= gfc_get_fake_result_decl (e
->symtree
->n
.sym
, 0);
1263 if (DECL_LANG_SPECIFIC (tmp
) && GFC_DECL_SAVED_DESCRIPTOR (tmp
))
1264 tmp
= GFC_DECL_SAVED_DESCRIPTOR (tmp
);
1266 slen
= build_zero_cst (size_type_node
);
1270 /* Remove everything after the last class reference, convert the
1271 expression and then recover its tailend once more. */
1273 ref
= class_ref
->next
;
1274 class_ref
->next
= NULL
;
1275 gfc_init_se (&tmpse
, NULL
);
1276 gfc_conv_expr (&tmpse
, e
);
1277 class_ref
->next
= ref
;
1279 slen
= tmpse
.string_length
;
1282 gcc_assert (tmp
!= NULL_TREE
);
1284 /* Dereference if needs be. */
1285 if (TREE_CODE (TREE_TYPE (tmp
)) == REFERENCE_TYPE
)
1286 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
1288 if (!(gfc_is_class_array_function (e
) && parmse
->class_vptr
))
1289 vptr
= gfc_class_vptr_get (tmp
);
1293 gfc_add_modify (&block
, ctree
,
1294 fold_convert (TREE_TYPE (ctree
), vptr
));
1296 /* Return the vptr component, except in the case of scalarized array
1297 references, where the dynamic type cannot change. */
1298 if (!elemental
&& full_array
&& copyback
)
1299 gfc_add_modify (&parmse
->post
, vptr
,
1300 fold_convert (TREE_TYPE (vptr
), ctree
));
1302 /* For unlimited polymorphic objects also set the _len component. */
1303 if (class_ts
.type
== BT_CLASS
1304 && class_ts
.u
.derived
->components
1305 && class_ts
.u
.derived
->components
->ts
.u
1306 .derived
->attr
.unlimited_polymorphic
)
1308 ctree
= gfc_class_len_get (var
);
1309 if (UNLIMITED_POLY (e
))
1310 tmp
= gfc_class_len_get (tmp
);
1311 else if (e
->ts
.type
== BT_CHARACTER
)
1313 gcc_assert (slen
!= NULL_TREE
);
1317 tmp
= build_zero_cst (size_type_node
);
1318 gfc_add_modify (&parmse
->pre
, ctree
,
1319 fold_convert (TREE_TYPE (ctree
), tmp
));
1321 /* Return the len component, except in the case of scalarized array
1322 references, where the dynamic type cannot change. */
1323 if (!elemental
&& full_array
&& copyback
1324 && (UNLIMITED_POLY (e
) || VAR_P (tmp
)))
1325 gfc_add_modify (&parmse
->post
, tmp
,
1326 fold_convert (TREE_TYPE (tmp
), ctree
));
1333 cond
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
1334 /* parmse->pre may contain some preparatory instructions for the
1335 temporary array descriptor. Those may only be executed when the
1336 optional argument is set, therefore add parmse->pre's instructions
1337 to block, which is later guarded by an if (optional_arg_given). */
1338 gfc_add_block_to_block (&parmse
->pre
, &block
);
1339 block
.head
= parmse
->pre
.head
;
1340 parmse
->pre
.head
= NULL_TREE
;
1341 tmp
= gfc_finish_block (&block
);
1343 if (optional_alloc_ptr
)
1344 tmp2
= build_empty_stmt (input_location
);
1347 gfc_init_block (&block
);
1349 tmp2
= gfc_conv_descriptor_data_get (gfc_class_data_get (var
));
1350 gfc_add_modify (&block
, tmp2
, fold_convert (TREE_TYPE (tmp2
),
1351 null_pointer_node
));
1352 tmp2
= gfc_finish_block (&block
);
1355 tmp
= build3_loc (input_location
, COND_EXPR
, void_type_node
,
1357 gfc_add_expr_to_block (&parmse
->pre
, tmp
);
1360 gfc_add_block_to_block (&parmse
->pre
, &block
);
1362 /* Pass the address of the class object. */
1363 parmse
->expr
= gfc_build_addr_expr (NULL_TREE
, var
);
1365 if (optional
&& optional_alloc_ptr
)
1366 parmse
->expr
= build3_loc (input_location
, COND_EXPR
,
1367 TREE_TYPE (parmse
->expr
),
1369 fold_convert (TREE_TYPE (parmse
->expr
),
1370 null_pointer_node
));
1374 /* Given a class array declaration and an index, returns the address
1375 of the referenced element. */
1378 gfc_get_class_array_ref (tree index
, tree class_decl
, tree data_comp
,
1381 tree data
, size
, tmp
, ctmp
, offset
, ptr
;
1383 data
= data_comp
!= NULL_TREE
? data_comp
:
1384 gfc_class_data_get (class_decl
);
1385 size
= gfc_class_vtab_size_get (class_decl
);
1389 tmp
= fold_convert (gfc_array_index_type
,
1390 gfc_class_len_get (class_decl
));
1391 ctmp
= fold_build2_loc (input_location
, MULT_EXPR
,
1392 gfc_array_index_type
, size
, tmp
);
1393 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
1394 logical_type_node
, tmp
,
1395 build_zero_cst (TREE_TYPE (tmp
)));
1396 size
= fold_build3_loc (input_location
, COND_EXPR
,
1397 gfc_array_index_type
, tmp
, ctmp
, size
);
1400 offset
= fold_build2_loc (input_location
, MULT_EXPR
,
1401 gfc_array_index_type
,
1404 data
= gfc_conv_descriptor_data_get (data
);
1405 ptr
= fold_convert (pvoid_type_node
, data
);
1406 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, offset
);
1407 return fold_convert (TREE_TYPE (data
), ptr
);
1411 /* Copies one class expression to another, assuming that if either
1412 'to' or 'from' are arrays they are packed. Should 'from' be
1413 NULL_TREE, the initialization expression for 'to' is used, assuming
1414 that the _vptr is set. */
1417 gfc_copy_class_to_class (tree from
, tree to
, tree nelems
, bool unlimited
)
1427 vec
<tree
, va_gc
> *args
;
1432 bool is_from_desc
= false, is_to_class
= false;
1435 /* To prevent warnings on uninitialized variables. */
1436 from_len
= to_len
= NULL_TREE
;
1438 if (from
!= NULL_TREE
)
1439 fcn
= gfc_class_vtab_copy_get (from
);
1441 fcn
= gfc_class_vtab_copy_get (to
);
1443 fcn_type
= TREE_TYPE (TREE_TYPE (fcn
));
1445 if (from
!= NULL_TREE
)
1447 is_from_desc
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from
));
1451 from
= GFC_DECL_SAVED_DESCRIPTOR (from
);
1455 /* Check that from is a class. When the class is part of a coarray,
1456 then from is a common pointer and is to be used as is. */
1457 tmp
= POINTER_TYPE_P (TREE_TYPE (from
))
1458 ? build_fold_indirect_ref (from
) : from
;
1460 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp
))
1461 || (DECL_P (tmp
) && GFC_DECL_CLASS (tmp
)))
1462 ? gfc_class_data_get (from
) : from
;
1463 is_from_desc
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data
));
1467 from_data
= gfc_class_vtab_def_init_get (to
);
1471 if (from
!= NULL_TREE
&& unlimited
)
1472 from_len
= gfc_class_len_or_zero_get (from
);
1474 from_len
= build_zero_cst (size_type_node
);
1477 if (GFC_CLASS_TYPE_P (TREE_TYPE (to
)))
1480 to_data
= gfc_class_data_get (to
);
1482 to_len
= gfc_class_len_get (to
);
1485 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1488 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data
)))
1490 stmtblock_t loopbody
;
1494 tree orig_nelems
= nelems
; /* Needed for bounds check. */
1496 gfc_init_block (&body
);
1497 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
1498 gfc_array_index_type
, nelems
,
1499 gfc_index_one_node
);
1500 nelems
= gfc_evaluate_now (tmp
, &body
);
1501 index
= gfc_create_var (gfc_array_index_type
, "S");
1505 from_ref
= gfc_get_class_array_ref (index
, from
, from_data
,
1507 vec_safe_push (args
, from_ref
);
1510 vec_safe_push (args
, from_data
);
1513 to_ref
= gfc_get_class_array_ref (index
, to
, to_data
, unlimited
);
1516 tmp
= gfc_conv_array_data (to
);
1517 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
1518 to_ref
= gfc_build_addr_expr (NULL_TREE
,
1519 gfc_build_array_ref (tmp
, index
, to
));
1521 vec_safe_push (args
, to_ref
);
1523 /* Add bounds check. */
1524 if ((gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
) > 0 && is_from_desc
)
1527 const char *name
= "<<unknown>>";
1531 name
= (const char *)(DECL_NAME (to
)->identifier
.id
.str
);
1533 from_len
= gfc_conv_descriptor_size (from_data
, 1);
1534 from_len
= fold_convert (TREE_TYPE (orig_nelems
), from_len
);
1535 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
1536 logical_type_node
, from_len
, orig_nelems
);
1537 msg
= xasprintf ("Array bound mismatch for dimension %d "
1538 "of array '%s' (%%ld/%%ld)",
1541 gfc_trans_runtime_check (true, false, tmp
, &body
,
1542 &gfc_current_locus
, msg
,
1543 fold_convert (long_integer_type_node
, orig_nelems
),
1544 fold_convert (long_integer_type_node
, from_len
));
1549 tmp
= build_call_vec (fcn_type
, fcn
, args
);
1551 /* Build the body of the loop. */
1552 gfc_init_block (&loopbody
);
1553 gfc_add_expr_to_block (&loopbody
, tmp
);
1555 /* Build the loop and return. */
1556 gfc_init_loopinfo (&loop
);
1558 loop
.from
[0] = gfc_index_zero_node
;
1559 loop
.loopvar
[0] = index
;
1560 loop
.to
[0] = nelems
;
1561 gfc_trans_scalarizing_loops (&loop
, &loopbody
);
1562 gfc_init_block (&ifbody
);
1563 gfc_add_block_to_block (&ifbody
, &loop
.pre
);
1564 stdcopy
= gfc_finish_block (&ifbody
);
1565 /* In initialization mode from_len is a constant zero. */
1566 if (unlimited
&& !integer_zerop (from_len
))
1568 vec_safe_push (args
, from_len
);
1569 vec_safe_push (args
, to_len
);
1570 tmp
= build_call_vec (fcn_type
, fcn
, args
);
1571 /* Build the body of the loop. */
1572 gfc_init_block (&loopbody
);
1573 gfc_add_expr_to_block (&loopbody
, tmp
);
1575 /* Build the loop and return. */
1576 gfc_init_loopinfo (&loop
);
1578 loop
.from
[0] = gfc_index_zero_node
;
1579 loop
.loopvar
[0] = index
;
1580 loop
.to
[0] = nelems
;
1581 gfc_trans_scalarizing_loops (&loop
, &loopbody
);
1582 gfc_init_block (&ifbody
);
1583 gfc_add_block_to_block (&ifbody
, &loop
.pre
);
1584 extcopy
= gfc_finish_block (&ifbody
);
1586 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
1587 logical_type_node
, from_len
,
1588 build_zero_cst (TREE_TYPE (from_len
)));
1589 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
1590 void_type_node
, tmp
, extcopy
, stdcopy
);
1591 gfc_add_expr_to_block (&body
, tmp
);
1592 tmp
= gfc_finish_block (&body
);
1596 gfc_add_expr_to_block (&body
, stdcopy
);
1597 tmp
= gfc_finish_block (&body
);
1599 gfc_cleanup_loop (&loop
);
1603 gcc_assert (!is_from_desc
);
1604 vec_safe_push (args
, from_data
);
1605 vec_safe_push (args
, to_data
);
1606 stdcopy
= build_call_vec (fcn_type
, fcn
, args
);
1608 /* In initialization mode from_len is a constant zero. */
1609 if (unlimited
&& !integer_zerop (from_len
))
1611 vec_safe_push (args
, from_len
);
1612 vec_safe_push (args
, to_len
);
1613 extcopy
= build_call_vec (fcn_type
, unshare_expr (fcn
), args
);
1614 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
1615 logical_type_node
, from_len
,
1616 build_zero_cst (TREE_TYPE (from_len
)));
1617 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
1618 void_type_node
, tmp
, extcopy
, stdcopy
);
1624 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1625 if (from
== NULL_TREE
)
1628 cond
= fold_build2_loc (input_location
, NE_EXPR
,
1630 from_data
, null_pointer_node
);
1631 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
1632 void_type_node
, cond
,
1633 tmp
, build_empty_stmt (input_location
));
1641 gfc_trans_class_array_init_assign (gfc_expr
*rhs
, gfc_expr
*lhs
, gfc_expr
*obj
)
1643 gfc_actual_arglist
*actual
;
1648 actual
= gfc_get_actual_arglist ();
1649 actual
->expr
= gfc_copy_expr (rhs
);
1650 actual
->next
= gfc_get_actual_arglist ();
1651 actual
->next
->expr
= gfc_copy_expr (lhs
);
1652 ppc
= gfc_copy_expr (obj
);
1653 gfc_add_vptr_component (ppc
);
1654 gfc_add_component_ref (ppc
, "_copy");
1655 ppc_code
= gfc_get_code (EXEC_CALL
);
1656 ppc_code
->resolved_sym
= ppc
->symtree
->n
.sym
;
1657 /* Although '_copy' is set to be elemental in class.cc, it is
1658 not staying that way. Find out why, sometime.... */
1659 ppc_code
->resolved_sym
->attr
.elemental
= 1;
1660 ppc_code
->ext
.actual
= actual
;
1661 ppc_code
->expr1
= ppc
;
1662 /* Since '_copy' is elemental, the scalarizer will take care
1663 of arrays in gfc_trans_call. */
1664 res
= gfc_trans_call (ppc_code
, false, NULL
, NULL
, false);
1665 gfc_free_statements (ppc_code
);
1667 if (UNLIMITED_POLY(obj
))
1669 /* Check if rhs is non-NULL. */
1671 gfc_init_se (&src
, NULL
);
1672 gfc_conv_expr (&src
, rhs
);
1673 src
.expr
= gfc_build_addr_expr (NULL_TREE
, src
.expr
);
1674 tree cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1675 src
.expr
, fold_convert (TREE_TYPE (src
.expr
),
1676 null_pointer_node
));
1677 res
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (res
), cond
, res
,
1678 build_empty_stmt (input_location
));
1684 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1685 A MEMCPY is needed to copy the full data from the default initializer
1686 of the dynamic type. */
1689 gfc_trans_class_init_assign (gfc_code
*code
)
1693 gfc_se dst
,src
,memsz
;
1694 gfc_expr
*lhs
, *rhs
, *sz
;
1696 gfc_start_block (&block
);
1698 lhs
= gfc_copy_expr (code
->expr1
);
1700 rhs
= gfc_copy_expr (code
->expr1
);
1701 gfc_add_vptr_component (rhs
);
1703 /* Make sure that the component backend_decls have been built, which
1704 will not have happened if the derived types concerned have not
1706 gfc_get_derived_type (rhs
->ts
.u
.derived
);
1707 gfc_add_def_init_component (rhs
);
1708 /* The _def_init is always scalar. */
1711 if (code
->expr1
->ts
.type
== BT_CLASS
1712 && CLASS_DATA (code
->expr1
)->attr
.dimension
)
1714 gfc_array_spec
*tmparr
= gfc_get_array_spec ();
1715 *tmparr
= *CLASS_DATA (code
->expr1
)->as
;
1716 /* Adding the array ref to the class expression results in correct
1717 indexing to the dynamic type. */
1718 gfc_add_full_array_ref (lhs
, tmparr
);
1719 tmp
= gfc_trans_class_array_init_assign (rhs
, lhs
, code
->expr1
);
1723 /* Scalar initialization needs the _data component. */
1724 gfc_add_data_component (lhs
);
1725 sz
= gfc_copy_expr (code
->expr1
);
1726 gfc_add_vptr_component (sz
);
1727 gfc_add_size_component (sz
);
1729 gfc_init_se (&dst
, NULL
);
1730 gfc_init_se (&src
, NULL
);
1731 gfc_init_se (&memsz
, NULL
);
1732 gfc_conv_expr (&dst
, lhs
);
1733 gfc_conv_expr (&src
, rhs
);
1734 gfc_conv_expr (&memsz
, sz
);
1735 gfc_add_block_to_block (&block
, &src
.pre
);
1736 src
.expr
= gfc_build_addr_expr (NULL_TREE
, src
.expr
);
1738 tmp
= gfc_build_memcpy_call (dst
.expr
, src
.expr
, memsz
.expr
);
1740 if (UNLIMITED_POLY(code
->expr1
))
1742 /* Check if _def_init is non-NULL. */
1743 tree cond
= fold_build2_loc (input_location
, NE_EXPR
,
1744 logical_type_node
, src
.expr
,
1745 fold_convert (TREE_TYPE (src
.expr
),
1746 null_pointer_node
));
1747 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (tmp
), cond
,
1748 tmp
, build_empty_stmt (input_location
));
1752 if (code
->expr1
->symtree
->n
.sym
->attr
.dummy
1753 && (code
->expr1
->symtree
->n
.sym
->attr
.optional
1754 || code
->expr1
->symtree
->n
.sym
->ns
->proc_name
->attr
.entry_master
))
1756 tree present
= gfc_conv_expr_present (code
->expr1
->symtree
->n
.sym
);
1757 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (tmp
),
1759 build_empty_stmt (input_location
));
1762 gfc_add_expr_to_block (&block
, tmp
);
1764 return gfc_finish_block (&block
);
1768 /* Class valued elemental function calls or class array elements arriving
1769 in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1770 is used to ensure that the rhs dynamic type is assigned to the lhs. */
1773 trans_scalar_class_assign (stmtblock_t
*block
, gfc_se
*lse
, gfc_se
*rse
)
1782 stmtblock_t inner_block
;
1784 bool not_call_expr
= TREE_CODE (rse
->expr
) != CALL_EXPR
;
1785 bool not_lhs_array_type
;
1787 /* Temporaries arising from dependencies in assignment get cast as a
1788 character type of the dynamic size of the rhs. Use the vptr copy
1790 tmp
= TREE_TYPE (lse
->expr
);
1791 not_lhs_array_type
= !(tmp
&& TREE_CODE (tmp
) == ARRAY_TYPE
1792 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp
)) != NULL_TREE
);
1794 /* Use ordinary assignment if the rhs is not a call expression or
1795 the lhs is not a class entity or an array(ie. character) type. */
1796 if ((not_call_expr
&& gfc_get_class_from_expr (lse
->expr
) == NULL_TREE
)
1797 && not_lhs_array_type
)
1800 /* Ordinary assignment can be used if both sides are class expressions
1801 since the dynamic type is preserved by copying the vptr. This
1802 should only occur, where temporaries are involved. */
1803 if (GFC_CLASS_TYPE_P (TREE_TYPE (lse
->expr
))
1804 && GFC_CLASS_TYPE_P (TREE_TYPE (rse
->expr
)))
1807 /* Fix the class expression and the class data of the rhs. */
1808 if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse
->expr
))
1811 tmp
= gfc_get_class_from_expr (rse
->expr
);
1812 if (tmp
== NULL_TREE
)
1814 rse_expr
= gfc_evaluate_now (tmp
, block
);
1817 rse_expr
= gfc_evaluate_now (rse
->expr
, block
);
1819 class_data
= gfc_class_data_get (rse_expr
);
1821 /* Check that the rhs data is not null. */
1822 is_descriptor
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data
));
1824 class_data
= gfc_conv_descriptor_data_get (class_data
);
1825 class_data
= gfc_evaluate_now (class_data
, block
);
1827 zero
= build_int_cst (TREE_TYPE (class_data
), 0);
1828 cond
= fold_build2_loc (input_location
, NE_EXPR
,
1832 /* Copy the rhs to the lhs. */
1833 fcn
= gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr
));
1834 fcn
= build_fold_indirect_ref_loc (input_location
, fcn
);
1835 tmp
= gfc_evaluate_now (gfc_build_addr_expr (NULL
, rse
->expr
), block
);
1836 tmp
= is_descriptor
? tmp
: class_data
;
1837 tmp
= build_call_expr_loc (input_location
, fcn
, 2, tmp
,
1838 gfc_build_addr_expr (NULL
, lse
->expr
));
1839 gfc_add_expr_to_block (block
, tmp
);
1841 /* Only elemental function results need to be finalised and freed. */
1845 /* Finalize the class data if needed. */
1846 gfc_init_block (&inner_block
);
1847 fcn
= gfc_vptr_final_get (gfc_class_vptr_get (rse_expr
));
1848 zero
= build_int_cst (TREE_TYPE (fcn
), 0);
1849 final_cond
= fold_build2_loc (input_location
, NE_EXPR
,
1850 logical_type_node
, fcn
, zero
);
1851 fcn
= build_fold_indirect_ref_loc (input_location
, fcn
);
1852 tmp
= build_call_expr_loc (input_location
, fcn
, 1, class_data
);
1853 tmp
= build3_v (COND_EXPR
, final_cond
,
1854 tmp
, build_empty_stmt (input_location
));
1855 gfc_add_expr_to_block (&inner_block
, tmp
);
1857 /* Free the class data. */
1858 tmp
= gfc_call_free (class_data
);
1859 tmp
= build3_v (COND_EXPR
, cond
, tmp
,
1860 build_empty_stmt (input_location
));
1861 gfc_add_expr_to_block (&inner_block
, tmp
);
1863 /* Finish the inner block and subject it to the condition on the
1864 class data being non-zero. */
1865 tmp
= gfc_finish_block (&inner_block
);
1866 tmp
= build3_v (COND_EXPR
, cond
, tmp
,
1867 build_empty_stmt (input_location
));
1868 gfc_add_expr_to_block (block
, tmp
);
1873 /* End of prototype trans-class.c */
1877 realloc_lhs_warning (bt type
, bool array
, locus
*where
)
1879 if (array
&& type
!= BT_CLASS
&& type
!= BT_DERIVED
&& warn_realloc_lhs
)
1880 gfc_warning (OPT_Wrealloc_lhs
,
1881 "Code for reallocating the allocatable array at %L will "
1883 else if (warn_realloc_lhs_all
)
1884 gfc_warning (OPT_Wrealloc_lhs_all
,
1885 "Code for reallocating the allocatable variable at %L "
1886 "will be added", where
);
1890 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
*,
1893 /* Copy the scalarization loop variables. */
1896 gfc_copy_se_loopvars (gfc_se
* dest
, gfc_se
* src
)
1899 dest
->loop
= src
->loop
;
1903 /* Initialize a simple expression holder.
1905 Care must be taken when multiple se are created with the same parent.
1906 The child se must be kept in sync. The easiest way is to delay creation
1907 of a child se until after the previous se has been translated. */
1910 gfc_init_se (gfc_se
* se
, gfc_se
* parent
)
1912 memset (se
, 0, sizeof (gfc_se
));
1913 gfc_init_block (&se
->pre
);
1914 gfc_init_block (&se
->post
);
1916 se
->parent
= parent
;
1919 gfc_copy_se_loopvars (se
, parent
);
1923 /* Advances to the next SS in the chain. Use this rather than setting
1924 se->ss = se->ss->next because all the parents needs to be kept in sync.
1928 gfc_advance_se_ss_chain (gfc_se
* se
)
1933 gcc_assert (se
!= NULL
&& se
->ss
!= NULL
&& se
->ss
!= gfc_ss_terminator
);
1936 /* Walk down the parent chain. */
1939 /* Simple consistency check. */
1940 gcc_assert (p
->parent
== NULL
|| p
->parent
->ss
== p
->ss
1941 || p
->parent
->ss
->nested_ss
== p
->ss
);
1943 /* If we were in a nested loop, the next scalarized expression can be
1944 on the parent ss' next pointer. Thus we should not take the next
1945 pointer blindly, but rather go up one nest level as long as next
1946 is the end of chain. */
1948 while (ss
->next
== gfc_ss_terminator
&& ss
->parent
!= NULL
)
1958 /* Ensures the result of the expression as either a temporary variable
1959 or a constant so that it can be used repeatedly. */
1962 gfc_make_safe_expr (gfc_se
* se
)
1966 if (CONSTANT_CLASS_P (se
->expr
))
1969 /* We need a temporary for this result. */
1970 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
1971 gfc_add_modify (&se
->pre
, var
, se
->expr
);
1976 /* Return an expression which determines if a dummy parameter is present.
1977 Also used for arguments to procedures with multiple entry points. */
1980 gfc_conv_expr_present (gfc_symbol
* sym
, bool use_saved_desc
)
1982 tree decl
, orig_decl
, cond
;
1984 gcc_assert (sym
->attr
.dummy
);
1985 orig_decl
= decl
= gfc_get_symbol_decl (sym
);
1987 /* Intrinsic scalars with VALUE attribute which are passed by value
1988 use a hidden argument to denote the present status. */
1989 if (sym
->attr
.value
&& !sym
->attr
.dimension
1990 && sym
->ts
.type
!= BT_CLASS
&& !gfc_bt_struct (sym
->ts
.type
))
1992 char name
[GFC_MAX_SYMBOL_LEN
+ 2];
1995 gcc_assert (TREE_CODE (decl
) == PARM_DECL
);
1997 strcpy (&name
[1], sym
->name
);
1998 tree_name
= get_identifier (name
);
2000 /* Walk function argument list to find hidden arg. */
2001 cond
= DECL_ARGUMENTS (DECL_CONTEXT (decl
));
2002 for ( ; cond
!= NULL_TREE
; cond
= TREE_CHAIN (cond
))
2003 if (DECL_NAME (cond
) == tree_name
2004 && DECL_ARTIFICIAL (cond
))
2011 /* Assumed-shape arrays use a local variable for the array data;
2012 the actual PARAM_DECL is in a saved decl. As the local variable
2013 is NULL, it can be checked instead, unless use_saved_desc is
2016 if (use_saved_desc
&& TREE_CODE (decl
) != PARM_DECL
)
2018 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
))
2019 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl
)));
2020 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
2023 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
, decl
,
2024 fold_convert (TREE_TYPE (decl
), null_pointer_node
));
2026 /* Fortran 2008 allows to pass null pointers and non-associated pointers
2027 as actual argument to denote absent dummies. For array descriptors,
2028 we thus also need to check the array descriptor. For BT_CLASS, it
2029 can also occur for scalars and F2003 due to type->class wrapping and
2030 class->class wrapping. Note further that BT_CLASS always uses an
2031 array descriptor for arrays, also for explicit-shape/assumed-size.
2032 For assumed-rank arrays, no local variable is generated, hence,
2033 the following also applies with !use_saved_desc. */
2035 if ((use_saved_desc
|| TREE_CODE (orig_decl
) == PARM_DECL
)
2036 && !sym
->attr
.allocatable
2037 && ((sym
->ts
.type
!= BT_CLASS
&& !sym
->attr
.pointer
)
2038 || (sym
->ts
.type
== BT_CLASS
2039 && !CLASS_DATA (sym
)->attr
.allocatable
2040 && !CLASS_DATA (sym
)->attr
.class_pointer
))
2041 && ((gfc_option
.allow_std
& GFC_STD_F2008
) != 0
2042 || sym
->ts
.type
== BT_CLASS
))
2046 if ((sym
->as
&& (sym
->as
->type
== AS_ASSUMED_SHAPE
2047 || sym
->as
->type
== AS_ASSUMED_RANK
2048 || sym
->attr
.codimension
))
2049 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)->as
))
2051 tmp
= build_fold_indirect_ref_loc (input_location
, decl
);
2052 if (sym
->ts
.type
== BT_CLASS
)
2053 tmp
= gfc_class_data_get (tmp
);
2054 tmp
= gfc_conv_array_data (tmp
);
2056 else if (sym
->ts
.type
== BT_CLASS
)
2057 tmp
= gfc_class_data_get (decl
);
2061 if (tmp
!= NULL_TREE
)
2063 tmp
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
, tmp
,
2064 fold_convert (TREE_TYPE (tmp
), null_pointer_node
));
2065 cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
2066 logical_type_node
, cond
, tmp
);
2074 /* Converts a missing, dummy argument into a null or zero. */
2077 gfc_conv_missing_dummy (gfc_se
* se
, gfc_expr
* arg
, gfc_typespec ts
, int kind
)
2082 present
= gfc_conv_expr_present (arg
->symtree
->n
.sym
);
2086 /* Create a temporary and convert it to the correct type. */
2087 tmp
= gfc_get_int_type (kind
);
2088 tmp
= fold_convert (tmp
, build_fold_indirect_ref_loc (input_location
,
2091 /* Test for a NULL value. */
2092 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (tmp
), present
,
2093 tmp
, fold_convert (TREE_TYPE (tmp
), integer_one_node
));
2094 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
2095 se
->expr
= gfc_build_addr_expr (NULL_TREE
, tmp
);
2099 tmp
= build3_loc (input_location
, COND_EXPR
, TREE_TYPE (se
->expr
),
2101 build_zero_cst (TREE_TYPE (se
->expr
)));
2102 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
2106 if (ts
.type
== BT_CHARACTER
)
2108 tmp
= build_int_cst (gfc_charlen_type_node
, 0);
2109 tmp
= fold_build3_loc (input_location
, COND_EXPR
, gfc_charlen_type_node
,
2110 present
, se
->string_length
, tmp
);
2111 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
2112 se
->string_length
= tmp
;
2118 /* Get the character length of an expression, looking through gfc_refs
2122 gfc_get_expr_charlen (gfc_expr
*e
)
2128 gcc_assert (e
->expr_type
== EXPR_VARIABLE
2129 && e
->ts
.type
== BT_CHARACTER
);
2131 length
= NULL
; /* To silence compiler warning. */
2133 if (is_subref_array (e
) && e
->ts
.u
.cl
->length
)
2136 gfc_init_se (&tmpse
, NULL
);
2137 gfc_conv_expr_type (&tmpse
, e
->ts
.u
.cl
->length
, gfc_charlen_type_node
);
2138 e
->ts
.u
.cl
->backend_decl
= tmpse
.expr
;
2142 /* First candidate: if the variable is of type CHARACTER, the
2143 expression's length could be the length of the character
2145 if (e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
)
2146 length
= e
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
;
2148 /* Look through the reference chain for component references. */
2149 for (r
= e
->ref
; r
; r
= r
->next
)
2154 if (r
->u
.c
.component
->ts
.type
== BT_CHARACTER
)
2155 length
= r
->u
.c
.component
->ts
.u
.cl
->backend_decl
;
2163 gfc_init_se (&se
, NULL
);
2164 gfc_conv_expr_type (&se
, r
->u
.ss
.start
, gfc_charlen_type_node
);
2166 gfc_conv_expr_type (&se
, r
->u
.ss
.end
, gfc_charlen_type_node
);
2167 length
= fold_build2_loc (input_location
, MINUS_EXPR
,
2168 gfc_charlen_type_node
,
2170 length
= fold_build2_loc (input_location
, PLUS_EXPR
,
2171 gfc_charlen_type_node
, length
,
2172 gfc_index_one_node
);
2181 gcc_assert (length
!= NULL
);
2186 /* Return for an expression the backend decl of the coarray. */
2189 gfc_get_tree_for_caf_expr (gfc_expr
*expr
)
2195 gcc_assert (expr
&& expr
->expr_type
== EXPR_VARIABLE
);
2197 /* Not-implemented diagnostic. */
2198 if (expr
->symtree
->n
.sym
->ts
.type
== BT_CLASS
2199 && UNLIMITED_POLY (expr
->symtree
->n
.sym
)
2200 && CLASS_DATA (expr
->symtree
->n
.sym
)->attr
.codimension
)
2201 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2202 "%L is not supported", &expr
->where
);
2204 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
2205 if (ref
->type
== REF_COMPONENT
)
2207 if (ref
->u
.c
.component
->ts
.type
== BT_CLASS
2208 && UNLIMITED_POLY (ref
->u
.c
.component
)
2209 && CLASS_DATA (ref
->u
.c
.component
)->attr
.codimension
)
2210 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2211 "component at %L is not supported", &expr
->where
);
2214 /* Make sure the backend_decl is present before accessing it. */
2215 caf_decl
= expr
->symtree
->n
.sym
->backend_decl
== NULL_TREE
2216 ? gfc_get_symbol_decl (expr
->symtree
->n
.sym
)
2217 : expr
->symtree
->n
.sym
->backend_decl
;
2219 if (expr
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
2221 if (expr
->ref
&& expr
->ref
->type
== REF_ARRAY
)
2223 caf_decl
= gfc_class_data_get (caf_decl
);
2224 if (CLASS_DATA (expr
->symtree
->n
.sym
)->attr
.codimension
)
2227 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
2229 if (ref
->type
== REF_COMPONENT
2230 && strcmp (ref
->u
.c
.component
->name
, "_data") != 0)
2232 caf_decl
= gfc_class_data_get (caf_decl
);
2233 if (CLASS_DATA (expr
->symtree
->n
.sym
)->attr
.codimension
)
2237 else if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.dimen
)
2241 if (expr
->symtree
->n
.sym
->attr
.codimension
)
2244 /* The following code assumes that the coarray is a component reachable via
2245 only scalar components/variables; the Fortran standard guarantees this. */
2247 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
2248 if (ref
->type
== REF_COMPONENT
)
2250 gfc_component
*comp
= ref
->u
.c
.component
;
2252 if (POINTER_TYPE_P (TREE_TYPE (caf_decl
)))
2253 caf_decl
= build_fold_indirect_ref_loc (input_location
, caf_decl
);
2254 caf_decl
= fold_build3_loc (input_location
, COMPONENT_REF
,
2255 TREE_TYPE (comp
->backend_decl
), caf_decl
,
2256 comp
->backend_decl
, NULL_TREE
);
2257 if (comp
->ts
.type
== BT_CLASS
)
2259 caf_decl
= gfc_class_data_get (caf_decl
);
2260 if (CLASS_DATA (comp
)->attr
.codimension
)
2266 if (comp
->attr
.codimension
)
2272 gcc_assert (found
&& caf_decl
);
2277 /* Obtain the Coarray token - and optionally also the offset. */
2280 gfc_get_caf_token_offset (gfc_se
*se
, tree
*token
, tree
*offset
, tree caf_decl
,
2281 tree se_expr
, gfc_expr
*expr
)
2285 /* Coarray token. */
2286 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl
)))
2288 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl
))
2289 == GFC_ARRAY_ALLOCATABLE
2290 || expr
->symtree
->n
.sym
->attr
.select_type_temporary
);
2291 *token
= gfc_conv_descriptor_token (caf_decl
);
2293 else if (DECL_LANG_SPECIFIC (caf_decl
)
2294 && GFC_DECL_TOKEN (caf_decl
) != NULL_TREE
)
2295 *token
= GFC_DECL_TOKEN (caf_decl
);
2298 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl
))
2299 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl
)) != NULL_TREE
);
2300 *token
= GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl
));
2306 /* Offset between the coarray base address and the address wanted. */
2307 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl
))
2308 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl
)) == GFC_ARRAY_ALLOCATABLE
2309 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl
)) == GFC_ARRAY_POINTER
))
2310 *offset
= build_int_cst (gfc_array_index_type
, 0);
2311 else if (DECL_LANG_SPECIFIC (caf_decl
)
2312 && GFC_DECL_CAF_OFFSET (caf_decl
) != NULL_TREE
)
2313 *offset
= GFC_DECL_CAF_OFFSET (caf_decl
);
2314 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl
)) != NULL_TREE
)
2315 *offset
= GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl
));
2317 *offset
= build_int_cst (gfc_array_index_type
, 0);
2319 if (POINTER_TYPE_P (TREE_TYPE (se_expr
))
2320 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr
))))
2322 tmp
= build_fold_indirect_ref_loc (input_location
, se_expr
);
2323 tmp
= gfc_conv_descriptor_data_get (tmp
);
2325 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr
)))
2326 tmp
= gfc_conv_descriptor_data_get (se_expr
);
2329 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr
)));
2333 *offset
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
2334 *offset
, fold_convert (gfc_array_index_type
, tmp
));
2336 if (expr
->symtree
->n
.sym
->ts
.type
== BT_DERIVED
2337 && expr
->symtree
->n
.sym
->attr
.codimension
2338 && expr
->symtree
->n
.sym
->ts
.u
.derived
->attr
.alloc_comp
)
2340 gfc_expr
*base_expr
= gfc_copy_expr (expr
);
2341 gfc_ref
*ref
= base_expr
->ref
;
2344 // Iterate through the refs until the last one.
2348 if (ref
->type
== REF_ARRAY
2349 && ref
->u
.ar
.type
!= AR_FULL
)
2351 const int ranksum
= ref
->u
.ar
.dimen
+ ref
->u
.ar
.codimen
;
2353 for (i
= 0; i
< ranksum
; ++i
)
2355 ref
->u
.ar
.start
[i
] = NULL
;
2356 ref
->u
.ar
.end
[i
] = NULL
;
2358 ref
->u
.ar
.type
= AR_FULL
;
2360 gfc_init_se (&base_se
, NULL
);
2361 if (gfc_caf_attr (base_expr
).dimension
)
2363 gfc_conv_expr_descriptor (&base_se
, base_expr
);
2364 tmp
= gfc_conv_descriptor_data_get (base_se
.expr
);
2368 gfc_conv_expr (&base_se
, base_expr
);
2372 gfc_free_expr (base_expr
);
2373 gfc_add_block_to_block (&se
->pre
, &base_se
.pre
);
2374 gfc_add_block_to_block (&se
->post
, &base_se
.post
);
2376 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl
)))
2377 tmp
= gfc_conv_descriptor_data_get (caf_decl
);
2380 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl
)));
2384 *offset
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
2385 fold_convert (gfc_array_index_type
, *offset
),
2386 fold_convert (gfc_array_index_type
, tmp
));
2390 /* Convert the coindex of a coarray into an image index; the result is
2391 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2392 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2395 gfc_caf_get_image_index (stmtblock_t
*block
, gfc_expr
*e
, tree desc
)
2398 tree lbound
, ubound
, extent
, tmp
, img_idx
;
2402 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
2403 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.codimen
> 0)
2405 gcc_assert (ref
!= NULL
);
2407 if (ref
->u
.ar
.dimen_type
[ref
->u
.ar
.dimen
] == DIMEN_THIS_IMAGE
)
2409 return build_call_expr_loc (input_location
, gfor_fndecl_caf_this_image
, 1,
2413 img_idx
= build_zero_cst (gfc_array_index_type
);
2414 extent
= build_one_cst (gfc_array_index_type
);
2415 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc
)))
2416 for (i
= ref
->u
.ar
.dimen
; i
< ref
->u
.ar
.dimen
+ ref
->u
.ar
.codimen
; i
++)
2418 gfc_init_se (&se
, NULL
);
2419 gfc_conv_expr_type (&se
, ref
->u
.ar
.start
[i
], gfc_array_index_type
);
2420 gfc_add_block_to_block (block
, &se
.pre
);
2421 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[i
]);
2422 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2423 TREE_TYPE (lbound
), se
.expr
, lbound
);
2424 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (tmp
),
2426 img_idx
= fold_build2_loc (input_location
, PLUS_EXPR
,
2427 TREE_TYPE (tmp
), img_idx
, tmp
);
2428 if (i
< ref
->u
.ar
.dimen
+ ref
->u
.ar
.codimen
- 1)
2430 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[i
]);
2431 tmp
= gfc_conv_array_extent_dim (lbound
, ubound
, NULL
);
2432 extent
= fold_build2_loc (input_location
, MULT_EXPR
,
2433 TREE_TYPE (tmp
), extent
, tmp
);
2437 for (i
= ref
->u
.ar
.dimen
; i
< ref
->u
.ar
.dimen
+ ref
->u
.ar
.codimen
; i
++)
2439 gfc_init_se (&se
, NULL
);
2440 gfc_conv_expr_type (&se
, ref
->u
.ar
.start
[i
], gfc_array_index_type
);
2441 gfc_add_block_to_block (block
, &se
.pre
);
2442 lbound
= GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc
), i
);
2443 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2444 TREE_TYPE (lbound
), se
.expr
, lbound
);
2445 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (tmp
),
2447 img_idx
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (tmp
),
2449 if (i
< ref
->u
.ar
.dimen
+ ref
->u
.ar
.codimen
- 1)
2451 ubound
= GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc
), i
);
2452 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
2453 TREE_TYPE (ubound
), ubound
, lbound
);
2454 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (tmp
),
2455 tmp
, build_one_cst (TREE_TYPE (tmp
)));
2456 extent
= fold_build2_loc (input_location
, MULT_EXPR
,
2457 TREE_TYPE (tmp
), extent
, tmp
);
2460 img_idx
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (img_idx
),
2461 img_idx
, build_one_cst (TREE_TYPE (img_idx
)));
2462 return fold_convert (integer_type_node
, img_idx
);
2466 /* For each character array constructor subexpression without a ts.u.cl->length,
2467 replace it by its first element (if there aren't any elements, the length
2468 should already be set to zero). */
2471 flatten_array_ctors_without_strlen (gfc_expr
* e
)
2473 gfc_actual_arglist
* arg
;
2479 switch (e
->expr_type
)
2483 flatten_array_ctors_without_strlen (e
->value
.op
.op1
);
2484 flatten_array_ctors_without_strlen (e
->value
.op
.op2
);
2488 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2492 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
2493 flatten_array_ctors_without_strlen (arg
->expr
);
2498 /* We've found what we're looking for. */
2499 if (e
->ts
.type
== BT_CHARACTER
&& !e
->ts
.u
.cl
->length
)
2504 gcc_assert (e
->value
.constructor
);
2506 c
= gfc_constructor_first (e
->value
.constructor
);
2510 flatten_array_ctors_without_strlen (new_expr
);
2511 gfc_replace_expr (e
, new_expr
);
2515 /* Otherwise, fall through to handle constructor elements. */
2517 case EXPR_STRUCTURE
:
2518 for (c
= gfc_constructor_first (e
->value
.constructor
);
2519 c
; c
= gfc_constructor_next (c
))
2520 flatten_array_ctors_without_strlen (c
->expr
);
2530 /* Generate code to initialize a string length variable. Returns the
2531 value. For array constructors, cl->length might be NULL and in this case,
2532 the first element of the constructor is needed. expr is the original
2533 expression so we can access it but can be NULL if this is not needed. */
2536 gfc_conv_string_length (gfc_charlen
* cl
, gfc_expr
* expr
, stmtblock_t
* pblock
)
2540 gfc_init_se (&se
, NULL
);
2542 if (!cl
->length
&& cl
->backend_decl
&& VAR_P (cl
->backend_decl
))
2545 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2546 "flatten" array constructors by taking their first element; all elements
2547 should be the same length or a cl->length should be present. */
2550 gfc_expr
* expr_flat
;
2553 expr_flat
= gfc_copy_expr (expr
);
2554 flatten_array_ctors_without_strlen (expr_flat
);
2555 gfc_resolve_expr (expr_flat
);
2557 gfc_conv_expr (&se
, expr_flat
);
2558 gfc_add_block_to_block (pblock
, &se
.pre
);
2559 cl
->backend_decl
= convert (gfc_charlen_type_node
, se
.string_length
);
2561 gfc_free_expr (expr_flat
);
2565 /* Convert cl->length. */
2567 gcc_assert (cl
->length
);
2569 gfc_conv_expr_type (&se
, cl
->length
, gfc_charlen_type_node
);
2570 se
.expr
= fold_build2_loc (input_location
, MAX_EXPR
, gfc_charlen_type_node
,
2571 se
.expr
, build_zero_cst (TREE_TYPE (se
.expr
)));
2572 gfc_add_block_to_block (pblock
, &se
.pre
);
2574 if (cl
->backend_decl
&& VAR_P (cl
->backend_decl
))
2575 gfc_add_modify (pblock
, cl
->backend_decl
, se
.expr
);
2577 cl
->backend_decl
= gfc_evaluate_now (se
.expr
, pblock
);
2582 gfc_conv_substring (gfc_se
* se
, gfc_ref
* ref
, int kind
,
2583 const char *name
, locus
*where
)
2593 type
= gfc_get_character_type (kind
, ref
->u
.ss
.length
);
2594 type
= build_pointer_type (type
);
2596 gfc_init_se (&start
, se
);
2597 gfc_conv_expr_type (&start
, ref
->u
.ss
.start
, gfc_charlen_type_node
);
2598 gfc_add_block_to_block (&se
->pre
, &start
.pre
);
2600 if (integer_onep (start
.expr
))
2601 gfc_conv_string_parameter (se
);
2606 /* Avoid multiple evaluation of substring start. */
2607 if (!CONSTANT_CLASS_P (tmp
) && !DECL_P (tmp
))
2608 start
.expr
= gfc_evaluate_now (start
.expr
, &se
->pre
);
2610 /* Change the start of the string. */
2611 if ((TREE_CODE (TREE_TYPE (se
->expr
)) == ARRAY_TYPE
2612 || TREE_CODE (TREE_TYPE (se
->expr
)) == INTEGER_TYPE
)
2613 && TYPE_STRING_FLAG (TREE_TYPE (se
->expr
)))
2616 tmp
= build_fold_indirect_ref_loc (input_location
,
2618 /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2619 if (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
2621 tmp
= gfc_build_array_ref (tmp
, start
.expr
, NULL_TREE
, true);
2622 se
->expr
= gfc_build_addr_expr (type
, tmp
);
2626 /* Length = end + 1 - start. */
2627 gfc_init_se (&end
, se
);
2628 if (ref
->u
.ss
.end
== NULL
)
2629 end
.expr
= se
->string_length
;
2632 gfc_conv_expr_type (&end
, ref
->u
.ss
.end
, gfc_charlen_type_node
);
2633 gfc_add_block_to_block (&se
->pre
, &end
.pre
);
2637 if (!CONSTANT_CLASS_P (tmp
) && !DECL_P (tmp
))
2638 end
.expr
= gfc_evaluate_now (end
.expr
, &se
->pre
);
2640 if ((gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
2641 && (ref
->u
.ss
.start
->symtree
2642 && !ref
->u
.ss
.start
->symtree
->n
.sym
->attr
.implied_index
))
2644 tree nonempty
= fold_build2_loc (input_location
, LE_EXPR
,
2645 logical_type_node
, start
.expr
,
2648 /* Check lower bound. */
2649 fault
= fold_build2_loc (input_location
, LT_EXPR
, logical_type_node
,
2651 build_one_cst (TREE_TYPE (start
.expr
)));
2652 fault
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
2653 logical_type_node
, nonempty
, fault
);
2655 msg
= xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2656 "is less than one", name
);
2658 msg
= xasprintf ("Substring out of bounds: lower bound (%%ld) "
2659 "is less than one");
2660 gfc_trans_runtime_check (true, false, fault
, &se
->pre
, where
, msg
,
2661 fold_convert (long_integer_type_node
,
2665 /* Check upper bound. */
2666 fault
= fold_build2_loc (input_location
, GT_EXPR
, logical_type_node
,
2667 end
.expr
, se
->string_length
);
2668 fault
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
2669 logical_type_node
, nonempty
, fault
);
2671 msg
= xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2672 "exceeds string length (%%ld)", name
);
2674 msg
= xasprintf ("Substring out of bounds: upper bound (%%ld) "
2675 "exceeds string length (%%ld)");
2676 gfc_trans_runtime_check (true, false, fault
, &se
->pre
, where
, msg
,
2677 fold_convert (long_integer_type_node
, end
.expr
),
2678 fold_convert (long_integer_type_node
,
2679 se
->string_length
));
2683 /* Try to calculate the length from the start and end expressions. */
2685 && gfc_dep_difference (ref
->u
.ss
.end
, ref
->u
.ss
.start
, &length
))
2687 HOST_WIDE_INT i_len
;
2689 i_len
= gfc_mpz_get_hwi (length
) + 1;
2693 tmp
= build_int_cst (gfc_charlen_type_node
, i_len
);
2694 mpz_clear (length
); /* Was initialized by gfc_dep_difference. */
2698 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_charlen_type_node
,
2699 fold_convert (gfc_charlen_type_node
, end
.expr
),
2700 fold_convert (gfc_charlen_type_node
, start
.expr
));
2701 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_charlen_type_node
,
2702 build_int_cst (gfc_charlen_type_node
, 1), tmp
);
2703 tmp
= fold_build2_loc (input_location
, MAX_EXPR
, gfc_charlen_type_node
,
2704 tmp
, build_int_cst (gfc_charlen_type_node
, 0));
2707 se
->string_length
= tmp
;
2711 /* Convert a derived type component reference. */
2714 gfc_conv_component_ref (gfc_se
* se
, gfc_ref
* ref
)
2722 c
= ref
->u
.c
.component
;
2724 if (c
->backend_decl
== NULL_TREE
2725 && ref
->u
.c
.sym
!= NULL
)
2726 gfc_get_derived_type (ref
->u
.c
.sym
);
2728 field
= c
->backend_decl
;
2729 gcc_assert (field
&& TREE_CODE (field
) == FIELD_DECL
);
2731 context
= DECL_FIELD_CONTEXT (field
);
2733 /* Components can correspond to fields of different containing
2734 types, as components are created without context, whereas
2735 a concrete use of a component has the type of decl as context.
2736 So, if the type doesn't match, we search the corresponding
2737 FIELD_DECL in the parent type. To not waste too much time
2738 we cache this result in norestrict_decl.
2739 On the other hand, if the context is a UNION or a MAP (a
2740 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2742 if (context
!= TREE_TYPE (decl
)
2743 && !( TREE_CODE (TREE_TYPE (field
)) == UNION_TYPE
/* Field is union */
2744 || TREE_CODE (context
) == UNION_TYPE
)) /* Field is map */
2746 tree f2
= c
->norestrict_decl
;
2747 if (!f2
|| DECL_FIELD_CONTEXT (f2
) != TREE_TYPE (decl
))
2748 for (f2
= TYPE_FIELDS (TREE_TYPE (decl
)); f2
; f2
= DECL_CHAIN (f2
))
2749 if (TREE_CODE (f2
) == FIELD_DECL
2750 && DECL_NAME (f2
) == DECL_NAME (field
))
2753 c
->norestrict_decl
= f2
;
2757 if (ref
->u
.c
.sym
&& ref
->u
.c
.sym
->ts
.type
== BT_CLASS
2758 && strcmp ("_data", c
->name
) == 0)
2760 /* Found a ref to the _data component. Store the associated ref to
2761 the vptr in se->class_vptr. */
2762 se
->class_vptr
= gfc_class_vptr_get (decl
);
2765 se
->class_vptr
= NULL_TREE
;
2767 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
2768 decl
, field
, NULL_TREE
);
2772 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2773 strlen () conditional below. */
2774 if (c
->ts
.type
== BT_CHARACTER
&& !c
->attr
.proc_pointer
2776 && !c
->attr
.pdt_string
)
2778 tmp
= c
->ts
.u
.cl
->backend_decl
;
2779 /* Components must always be constant length. */
2780 gcc_assert (tmp
&& INTEGER_CST_P (tmp
));
2781 se
->string_length
= tmp
;
2784 if (gfc_deferred_strlen (c
, &field
))
2786 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
,
2788 decl
, field
, NULL_TREE
);
2789 se
->string_length
= tmp
;
2792 if (((c
->attr
.pointer
|| c
->attr
.allocatable
)
2793 && (!c
->attr
.dimension
&& !c
->attr
.codimension
)
2794 && c
->ts
.type
!= BT_CHARACTER
)
2795 || c
->attr
.proc_pointer
)
2796 se
->expr
= build_fold_indirect_ref_loc (input_location
,
2801 /* This function deals with component references to components of the
2802 parent type for derived type extensions. */
2804 conv_parent_component_references (gfc_se
* se
, gfc_ref
* ref
)
2812 c
= ref
->u
.c
.component
;
2814 /* Return if the component is in this type, i.e. not in the parent type. */
2815 for (cmp
= dt
->components
; cmp
; cmp
= cmp
->next
)
2819 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2820 parent
.type
= REF_COMPONENT
;
2822 parent
.u
.c
.sym
= dt
;
2823 parent
.u
.c
.component
= dt
->components
;
2825 if (dt
->backend_decl
== NULL
)
2826 gfc_get_derived_type (dt
);
2828 /* Build the reference and call self. */
2829 gfc_conv_component_ref (se
, &parent
);
2830 parent
.u
.c
.sym
= dt
->components
->ts
.u
.derived
;
2831 parent
.u
.c
.component
= c
;
2832 conv_parent_component_references (se
, &parent
);
2837 conv_inquiry (gfc_se
* se
, gfc_ref
* ref
, gfc_expr
*expr
, gfc_typespec
*ts
)
2839 tree res
= se
->expr
;
2844 res
= fold_build1_loc (input_location
, REALPART_EXPR
,
2845 TREE_TYPE (TREE_TYPE (res
)), res
);
2849 res
= fold_build1_loc (input_location
, IMAGPART_EXPR
,
2850 TREE_TYPE (TREE_TYPE (res
)), res
);
2854 res
= build_int_cst (gfc_typenode_for_spec (&expr
->ts
),
2859 res
= fold_convert (gfc_typenode_for_spec (&expr
->ts
),
2869 /* Dereference VAR where needed if it is a pointer, reference, etc.
2870 according to Fortran semantics. */
2873 gfc_maybe_dereference_var (gfc_symbol
*sym
, tree var
, bool descriptor_only_p
,
2876 if (!POINTER_TYPE_P (TREE_TYPE (var
)))
2878 if (is_CFI_desc (sym
, NULL
))
2879 return build_fold_indirect_ref_loc (input_location
, var
);
2881 /* Characters are entirely different from other types, they are treated
2883 if (sym
->ts
.type
== BT_CHARACTER
)
2885 /* Dereference character pointer dummy arguments
2887 if ((sym
->attr
.pointer
|| sym
->attr
.allocatable
2888 || (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
))
2890 || sym
->attr
.function
2891 || sym
->attr
.result
))
2892 var
= build_fold_indirect_ref_loc (input_location
, var
);
2894 else if (!sym
->attr
.value
)
2896 /* Dereference temporaries for class array dummy arguments. */
2897 if (sym
->attr
.dummy
&& is_classarray
2898 && GFC_ARRAY_TYPE_P (TREE_TYPE (var
)))
2900 if (!descriptor_only_p
)
2901 var
= GFC_DECL_SAVED_DESCRIPTOR (var
);
2903 var
= build_fold_indirect_ref_loc (input_location
, var
);
2906 /* Dereference non-character scalar dummy arguments. */
2907 if (sym
->attr
.dummy
&& !sym
->attr
.dimension
2908 && !(sym
->attr
.codimension
&& sym
->attr
.allocatable
)
2909 && (sym
->ts
.type
!= BT_CLASS
2910 || (!CLASS_DATA (sym
)->attr
.dimension
2911 && !(CLASS_DATA (sym
)->attr
.codimension
2912 && CLASS_DATA (sym
)->attr
.allocatable
))))
2913 var
= build_fold_indirect_ref_loc (input_location
, var
);
2915 /* Dereference scalar hidden result. */
2916 if (flag_f2c
&& sym
->ts
.type
== BT_COMPLEX
2917 && (sym
->attr
.function
|| sym
->attr
.result
)
2918 && !sym
->attr
.dimension
&& !sym
->attr
.pointer
2919 && !sym
->attr
.always_explicit
)
2920 var
= build_fold_indirect_ref_loc (input_location
, var
);
2922 /* Dereference non-character, non-class pointer variables.
2923 These must be dummies, results, or scalars. */
2925 && (sym
->attr
.pointer
|| sym
->attr
.allocatable
2926 || gfc_is_associate_pointer (sym
)
2927 || (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
))
2929 || sym
->attr
.function
2931 || (!sym
->attr
.dimension
2932 && (!sym
->attr
.codimension
|| !sym
->attr
.allocatable
))))
2933 var
= build_fold_indirect_ref_loc (input_location
, var
);
2934 /* Now treat the class array pointer variables accordingly. */
2935 else if (sym
->ts
.type
== BT_CLASS
2937 && (CLASS_DATA (sym
)->attr
.dimension
2938 || CLASS_DATA (sym
)->attr
.codimension
)
2939 && ((CLASS_DATA (sym
)->as
2940 && CLASS_DATA (sym
)->as
->type
== AS_ASSUMED_RANK
)
2941 || CLASS_DATA (sym
)->attr
.allocatable
2942 || CLASS_DATA (sym
)->attr
.class_pointer
))
2943 var
= build_fold_indirect_ref_loc (input_location
, var
);
2944 /* And the case where a non-dummy, non-result, non-function,
2945 non-allocable and non-pointer classarray is present. This case was
2946 previously covered by the first if, but with introducing the
2947 condition !is_classarray there, that case has to be covered
2949 else if (sym
->ts
.type
== BT_CLASS
2951 && !sym
->attr
.function
2952 && !sym
->attr
.result
2953 && (CLASS_DATA (sym
)->attr
.dimension
2954 || CLASS_DATA (sym
)->attr
.codimension
)
2956 || !CLASS_DATA (sym
)->attr
.allocatable
)
2957 && !CLASS_DATA (sym
)->attr
.class_pointer
)
2958 var
= build_fold_indirect_ref_loc (input_location
, var
);
2964 /* Return the contents of a variable. Also handles reference/pointer
2965 variables (all Fortran pointer references are implicit). */
2968 gfc_conv_variable (gfc_se
* se
, gfc_expr
* expr
)
2973 tree parent_decl
= NULL_TREE
;
2976 bool alternate_entry
;
2979 bool first_time
= true;
2981 sym
= expr
->symtree
->n
.sym
;
2982 is_classarray
= IS_CLASS_ARRAY (sym
);
2986 gfc_ss_info
*ss_info
= ss
->info
;
2988 /* Check that something hasn't gone horribly wrong. */
2989 gcc_assert (ss
!= gfc_ss_terminator
);
2990 gcc_assert (ss_info
->expr
== expr
);
2992 /* A scalarized term. We already know the descriptor. */
2993 se
->expr
= ss_info
->data
.array
.descriptor
;
2994 se
->string_length
= ss_info
->string_length
;
2995 ref
= ss_info
->data
.array
.ref
;
2997 gcc_assert (ref
->type
== REF_ARRAY
2998 && ref
->u
.ar
.type
!= AR_ELEMENT
);
3000 gfc_conv_tmp_array_ref (se
);
3004 tree se_expr
= NULL_TREE
;
3006 se
->expr
= gfc_get_symbol_decl (sym
);
3008 /* Deal with references to a parent results or entries by storing
3009 the current_function_decl and moving to the parent_decl. */
3010 return_value
= sym
->attr
.function
&& sym
->result
== sym
;
3011 alternate_entry
= sym
->attr
.function
&& sym
->attr
.entry
3012 && sym
->result
== sym
;
3013 entry_master
= sym
->attr
.result
3014 && sym
->ns
->proc_name
->attr
.entry_master
3015 && !gfc_return_by_reference (sym
->ns
->proc_name
);
3016 if (current_function_decl
)
3017 parent_decl
= DECL_CONTEXT (current_function_decl
);
3019 if ((se
->expr
== parent_decl
&& return_value
)
3020 || (sym
->ns
&& sym
->ns
->proc_name
3022 && sym
->ns
->proc_name
->backend_decl
== parent_decl
3023 && (alternate_entry
|| entry_master
)))
3028 /* Special case for assigning the return value of a function.
3029 Self recursive functions must have an explicit return value. */
3030 if (return_value
&& (se
->expr
== current_function_decl
|| parent_flag
))
3031 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
3033 /* Similarly for alternate entry points. */
3034 else if (alternate_entry
3035 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
3038 gfc_entry_list
*el
= NULL
;
3040 for (el
= sym
->ns
->entries
; el
; el
= el
->next
)
3043 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
3048 else if (entry_master
3049 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
3051 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
3056 /* Procedure actual arguments. Look out for temporary variables
3057 with the same attributes as function values. */
3058 else if (!sym
->attr
.temporary
3059 && sym
->attr
.flavor
== FL_PROCEDURE
3060 && se
->expr
!= current_function_decl
)
3062 if (!sym
->attr
.dummy
&& !sym
->attr
.proc_pointer
)
3064 gcc_assert (TREE_CODE (se
->expr
) == FUNCTION_DECL
);
3065 se
->expr
= gfc_build_addr_expr (NULL_TREE
, se
->expr
);
3070 /* Dereference the expression, where needed. */
3071 se
->expr
= gfc_maybe_dereference_var (sym
, se
->expr
, se
->descriptor_only
,
3077 /* For character variables, also get the length. */
3078 if (sym
->ts
.type
== BT_CHARACTER
)
3080 /* If the character length of an entry isn't set, get the length from
3081 the master function instead. */
3082 if (sym
->attr
.entry
&& !sym
->ts
.u
.cl
->backend_decl
)
3083 se
->string_length
= sym
->ns
->proc_name
->ts
.u
.cl
->backend_decl
;
3085 se
->string_length
= sym
->ts
.u
.cl
->backend_decl
;
3086 gcc_assert (se
->string_length
);
3089 gfc_typespec
*ts
= &sym
->ts
;
3095 /* Return the descriptor if that's what we want and this is an array
3096 section reference. */
3097 if (se
->descriptor_only
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
3099 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
3100 /* Return the descriptor for array pointers and allocations. */
3101 if (se
->want_pointer
3102 && ref
->next
== NULL
&& (se
->descriptor_only
))
3105 gfc_conv_array_ref (se
, &ref
->u
.ar
, expr
, &expr
->where
);
3106 /* Return a pointer to an element. */
3110 ts
= &ref
->u
.c
.component
->ts
;
3111 if (first_time
&& is_classarray
&& sym
->attr
.dummy
3112 && se
->descriptor_only
3113 && !CLASS_DATA (sym
)->attr
.allocatable
3114 && !CLASS_DATA (sym
)->attr
.class_pointer
3115 && CLASS_DATA (sym
)->as
3116 && CLASS_DATA (sym
)->as
->type
!= AS_ASSUMED_RANK
3117 && strcmp ("_data", ref
->u
.c
.component
->name
) == 0)
3118 /* Skip the first ref of a _data component, because for class
3119 arrays that one is already done by introducing a temporary
3120 array descriptor. */
3123 if (ref
->u
.c
.sym
->attr
.extension
)
3124 conv_parent_component_references (se
, ref
);
3126 gfc_conv_component_ref (se
, ref
);
3127 if (!ref
->next
&& ref
->u
.c
.sym
->attr
.codimension
3128 && se
->want_pointer
&& se
->descriptor_only
)
3134 gfc_conv_substring (se
, ref
, expr
->ts
.kind
,
3135 expr
->symtree
->name
, &expr
->where
);
3139 conv_inquiry (se
, ref
, expr
, ts
);
3149 /* Pointer assignment, allocation or pass by reference. Arrays are handled
3151 if (se
->want_pointer
)
3153 if (expr
->ts
.type
== BT_CHARACTER
&& !gfc_is_proc_ptr_comp (expr
))
3154 gfc_conv_string_parameter (se
);
3156 se
->expr
= gfc_build_addr_expr (NULL_TREE
, se
->expr
);
3161 /* Unary ops are easy... Or they would be if ! was a valid op. */
3164 gfc_conv_unary_op (enum tree_code code
, gfc_se
* se
, gfc_expr
* expr
)
3169 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
3170 /* Initialize the operand. */
3171 gfc_init_se (&operand
, se
);
3172 gfc_conv_expr_val (&operand
, expr
->value
.op
.op1
);
3173 gfc_add_block_to_block (&se
->pre
, &operand
.pre
);
3175 type
= gfc_typenode_for_spec (&expr
->ts
);
3177 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3178 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3179 All other unary operators have an equivalent GIMPLE unary operator. */
3180 if (code
== TRUTH_NOT_EXPR
)
3181 se
->expr
= fold_build2_loc (input_location
, EQ_EXPR
, type
, operand
.expr
,
3182 build_int_cst (type
, 0));
3184 se
->expr
= fold_build1_loc (input_location
, code
, type
, operand
.expr
);
3188 /* Expand power operator to optimal multiplications when a value is raised
3189 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3190 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3191 Programming", 3rd Edition, 1998. */
3193 /* This code is mostly duplicated from expand_powi in the backend.
3194 We establish the "optimal power tree" lookup table with the defined size.
3195 The items in the table are the exponents used to calculate the index
3196 exponents. Any integer n less than the value can get an "addition chain",
3197 with the first node being one. */
3198 #define POWI_TABLE_SIZE 256
3200 /* The table is from builtins.cc. */
3201 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
3203 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3204 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3205 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3206 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3207 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3208 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3209 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3210 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3211 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3212 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3213 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3214 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3215 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3216 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3217 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3218 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3219 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3220 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3221 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3222 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3223 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3224 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3225 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3226 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3227 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3228 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3229 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3230 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3231 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3232 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3233 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3234 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3237 /* If n is larger than lookup table's max index, we use the "window
3239 #define POWI_WINDOW_SIZE 3
3241 /* Recursive function to expand the power operator. The temporary
3242 values are put in tmpvar. The function returns tmpvar[1] ** n. */
3244 gfc_conv_powi (gfc_se
* se
, unsigned HOST_WIDE_INT n
, tree
* tmpvar
)
3251 if (n
< POWI_TABLE_SIZE
)
3256 op0
= gfc_conv_powi (se
, n
- powi_table
[n
], tmpvar
);
3257 op1
= gfc_conv_powi (se
, powi_table
[n
], tmpvar
);
3261 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
3262 op0
= gfc_conv_powi (se
, n
- digit
, tmpvar
);
3263 op1
= gfc_conv_powi (se
, digit
, tmpvar
);
3267 op0
= gfc_conv_powi (se
, n
>> 1, tmpvar
);
3271 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (op0
), op0
, op1
);
3272 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
3274 if (n
< POWI_TABLE_SIZE
)
3281 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3282 return 1. Else return 0 and a call to runtime library functions
3283 will have to be built. */
3285 gfc_conv_cst_int_power (gfc_se
* se
, tree lhs
, tree rhs
)
3290 tree vartmp
[POWI_TABLE_SIZE
];
3292 unsigned HOST_WIDE_INT n
;
3294 wi::tree_to_wide_ref wrhs
= wi::to_wide (rhs
);
3296 /* If exponent is too large, we won't expand it anyway, so don't bother
3297 with large integer values. */
3298 if (!wi::fits_shwi_p (wrhs
))
3301 m
= wrhs
.to_shwi ();
3302 /* Use the wide_int's routine to reliably get the absolute value on all
3303 platforms. Then convert it to a HOST_WIDE_INT like above. */
3304 n
= wi::abs (wrhs
).to_shwi ();
3306 type
= TREE_TYPE (lhs
);
3307 sgn
= tree_int_cst_sgn (rhs
);
3309 if (((FLOAT_TYPE_P (type
) && !flag_unsafe_math_optimizations
)
3310 || optimize_size
) && (m
> 2 || m
< -1))
3316 se
->expr
= gfc_build_const (type
, integer_one_node
);
3320 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3321 if ((sgn
== -1) && (TREE_CODE (type
) == INTEGER_TYPE
))
3323 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
3324 lhs
, build_int_cst (TREE_TYPE (lhs
), -1));
3325 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
3326 lhs
, build_int_cst (TREE_TYPE (lhs
), 1));
3329 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3332 tmp
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
3333 logical_type_node
, tmp
, cond
);
3334 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
,
3335 tmp
, build_int_cst (type
, 1),
3336 build_int_cst (type
, 0));
3340 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3341 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, tmp
,
3342 build_int_cst (type
, -1),
3343 build_int_cst (type
, 0));
3344 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
,
3345 cond
, build_int_cst (type
, 1), tmp
);
3349 memset (vartmp
, 0, sizeof (vartmp
));
3353 tmp
= gfc_build_const (type
, integer_one_node
);
3354 vartmp
[1] = fold_build2_loc (input_location
, RDIV_EXPR
, type
, tmp
,
3358 se
->expr
= gfc_conv_powi (se
, n
, vartmp
);
3364 /* Power op (**). Constant integer exponent has special handling. */
3367 gfc_conv_power_op (gfc_se
* se
, gfc_expr
* expr
)
3369 tree gfc_int4_type_node
;
3372 int res_ikind_1
, res_ikind_2
;
3377 gfc_init_se (&lse
, se
);
3378 gfc_conv_expr_val (&lse
, expr
->value
.op
.op1
);
3379 lse
.expr
= gfc_evaluate_now (lse
.expr
, &lse
.pre
);
3380 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
3382 gfc_init_se (&rse
, se
);
3383 gfc_conv_expr_val (&rse
, expr
->value
.op
.op2
);
3384 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
3386 if (expr
->value
.op
.op2
->ts
.type
== BT_INTEGER
3387 && expr
->value
.op
.op2
->expr_type
== EXPR_CONSTANT
)
3388 if (gfc_conv_cst_int_power (se
, lse
.expr
, rse
.expr
))
3391 if (INTEGER_CST_P (lse
.expr
)
3392 && TREE_CODE (TREE_TYPE (rse
.expr
)) == INTEGER_TYPE
)
3394 wi::tree_to_wide_ref wlhs
= wi::to_wide (lse
.expr
);
3396 int kind
, ikind
, bit_size
;
3398 v
= wlhs
.to_shwi ();
3401 kind
= expr
->value
.op
.op1
->ts
.kind
;
3402 ikind
= gfc_validate_kind (BT_INTEGER
, kind
, false);
3403 bit_size
= gfc_integer_kinds
[ikind
].bit_size
;
3407 /* 1**something is always 1. */
3408 se
->expr
= build_int_cst (TREE_TYPE (lse
.expr
), 1);
3413 /* (-1)**n is 1 - ((n & 1) << 1) */
3417 type
= TREE_TYPE (lse
.expr
);
3418 tmp
= fold_build2_loc (input_location
, BIT_AND_EXPR
, type
,
3419 rse
.expr
, build_int_cst (type
, 1));
3420 tmp
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
3421 tmp
, build_int_cst (type
, 1));
3422 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, type
,
3423 build_int_cst (type
, 1), tmp
);
3427 else if (w
> 0 && ((w
& (w
-1)) == 0) && ((w
>> (bit_size
-1)) == 0))
3429 /* Here v is +/- 2**e. The further simplification uses
3430 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3431 1<<(4*n), etc., but we have to make sure to return zero
3432 if the number of bits is too large. */
3442 type
= TREE_TYPE (lse
.expr
);
3447 shift
= fold_build2_loc (input_location
, PLUS_EXPR
,
3448 TREE_TYPE (rse
.expr
),
3449 rse
.expr
, rse
.expr
);
3452 /* use popcount for fast log2(w) */
3453 int e
= wi::popcount (w
-1);
3454 shift
= fold_build2_loc (input_location
, MULT_EXPR
,
3455 TREE_TYPE (rse
.expr
),
3456 build_int_cst (TREE_TYPE (rse
.expr
), e
),
3460 lshift
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
3461 build_int_cst (type
, 1), shift
);
3462 ge
= fold_build2_loc (input_location
, GE_EXPR
, logical_type_node
,
3463 rse
.expr
, build_int_cst (type
, 0));
3464 cond
= fold_build3_loc (input_location
, COND_EXPR
, type
, ge
, lshift
,
3465 build_int_cst (type
, 0));
3466 num_bits
= build_int_cst (TREE_TYPE (rse
.expr
), TYPE_PRECISION (type
));
3467 cond2
= fold_build2_loc (input_location
, GE_EXPR
, logical_type_node
,
3468 rse
.expr
, num_bits
);
3469 tmp1
= fold_build3_loc (input_location
, COND_EXPR
, type
, cond2
,
3470 build_int_cst (type
, 0), cond
);
3477 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3479 tmp2
= fold_build2_loc (input_location
, BIT_AND_EXPR
, type
,
3480 rse
.expr
, build_int_cst (type
, 1));
3481 tmp2
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
3482 tmp2
, build_int_cst (type
, 1));
3483 tmp2
= fold_build2_loc (input_location
, MINUS_EXPR
, type
,
3484 build_int_cst (type
, 1), tmp2
);
3485 se
->expr
= fold_build2_loc (input_location
, MULT_EXPR
, type
,
3492 gfc_int4_type_node
= gfc_get_int_type (4);
3494 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3495 library routine. But in the end, we have to convert the result back
3496 if this case applies -- with res_ikind_K, we keep track whether operand K
3497 falls into this case. */
3501 kind
= expr
->value
.op
.op1
->ts
.kind
;
3502 switch (expr
->value
.op
.op2
->ts
.type
)
3505 ikind
= expr
->value
.op
.op2
->ts
.kind
;
3510 rse
.expr
= convert (gfc_int4_type_node
, rse
.expr
);
3511 res_ikind_2
= ikind
;
3533 if (expr
->value
.op
.op1
->ts
.type
== BT_INTEGER
)
3535 lse
.expr
= convert (gfc_int4_type_node
, lse
.expr
);
3562 switch (expr
->value
.op
.op1
->ts
.type
)
3565 if (kind
== 3) /* Case 16 was not handled properly above. */
3567 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].integer
;
3571 /* Use builtins for real ** int4. */
3577 fndecl
= builtin_decl_explicit (BUILT_IN_POWIF
);
3581 fndecl
= builtin_decl_explicit (BUILT_IN_POWI
);
3585 fndecl
= builtin_decl_explicit (BUILT_IN_POWIL
);
3589 /* Use the __builtin_powil() only if real(kind=16) is
3590 actually the C long double type. */
3591 if (!gfc_real16_is_float128
)
3592 fndecl
= builtin_decl_explicit (BUILT_IN_POWIL
);
3600 /* If we don't have a good builtin for this, go for the
3601 library function. */
3603 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].real
;
3607 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].cmplx
;
3616 fndecl
= gfc_builtin_decl_for_float_kind (BUILT_IN_POW
, kind
);
3620 fndecl
= gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW
, kind
);
3628 se
->expr
= build_call_expr_loc (input_location
,
3629 fndecl
, 2, lse
.expr
, rse
.expr
);
3631 /* Convert the result back if it is of wrong integer kind. */
3632 if (res_ikind_1
!= -1 && res_ikind_2
!= -1)
3634 /* We want the maximum of both operand kinds as result. */
3635 if (res_ikind_1
< res_ikind_2
)
3636 res_ikind_1
= res_ikind_2
;
3637 se
->expr
= convert (gfc_get_int_type (res_ikind_1
), se
->expr
);
3642 /* Generate code to allocate a string temporary. */
3645 gfc_conv_string_tmp (gfc_se
* se
, tree type
, tree len
)
3650 if (gfc_can_put_var_on_stack (len
))
3652 /* Create a temporary variable to hold the result. */
3653 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
3654 TREE_TYPE (len
), len
,
3655 build_int_cst (TREE_TYPE (len
), 1));
3656 tmp
= build_range_type (gfc_charlen_type_node
, size_zero_node
, tmp
);
3658 if (TREE_CODE (TREE_TYPE (type
)) == ARRAY_TYPE
)
3659 tmp
= build_array_type (TREE_TYPE (TREE_TYPE (type
)), tmp
);
3661 tmp
= build_array_type (TREE_TYPE (type
), tmp
);
3663 var
= gfc_create_var (tmp
, "str");
3664 var
= gfc_build_addr_expr (type
, var
);
3668 /* Allocate a temporary to hold the result. */
3669 var
= gfc_create_var (type
, "pstr");
3670 gcc_assert (POINTER_TYPE_P (type
));
3671 tmp
= TREE_TYPE (type
);
3672 if (TREE_CODE (tmp
) == ARRAY_TYPE
)
3673 tmp
= TREE_TYPE (tmp
);
3674 tmp
= TYPE_SIZE_UNIT (tmp
);
3675 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
3676 fold_convert (size_type_node
, len
),
3677 fold_convert (size_type_node
, tmp
));
3678 tmp
= gfc_call_malloc (&se
->pre
, type
, tmp
);
3679 gfc_add_modify (&se
->pre
, var
, tmp
);
3681 /* Free the temporary afterwards. */
3682 tmp
= gfc_call_free (var
);
3683 gfc_add_expr_to_block (&se
->post
, tmp
);
3690 /* Handle a string concatenation operation. A temporary will be allocated to
3694 gfc_conv_concat_op (gfc_se
* se
, gfc_expr
* expr
)
3697 tree len
, type
, var
, tmp
, fndecl
;
3699 gcc_assert (expr
->value
.op
.op1
->ts
.type
== BT_CHARACTER
3700 && expr
->value
.op
.op2
->ts
.type
== BT_CHARACTER
);
3701 gcc_assert (expr
->value
.op
.op1
->ts
.kind
== expr
->value
.op
.op2
->ts
.kind
);
3703 gfc_init_se (&lse
, se
);
3704 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
3705 gfc_conv_string_parameter (&lse
);
3706 gfc_init_se (&rse
, se
);
3707 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
3708 gfc_conv_string_parameter (&rse
);
3710 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
3711 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
3713 type
= gfc_get_character_type (expr
->ts
.kind
, expr
->ts
.u
.cl
);
3714 len
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
3715 if (len
== NULL_TREE
)
3717 len
= fold_build2_loc (input_location
, PLUS_EXPR
,
3718 gfc_charlen_type_node
,
3719 fold_convert (gfc_charlen_type_node
,
3721 fold_convert (gfc_charlen_type_node
,
3722 rse
.string_length
));
3725 type
= build_pointer_type (type
);
3727 var
= gfc_conv_string_tmp (se
, type
, len
);
3729 /* Do the actual concatenation. */
3730 if (expr
->ts
.kind
== 1)
3731 fndecl
= gfor_fndecl_concat_string
;
3732 else if (expr
->ts
.kind
== 4)
3733 fndecl
= gfor_fndecl_concat_string_char4
;
3737 tmp
= build_call_expr_loc (input_location
,
3738 fndecl
, 6, len
, var
, lse
.string_length
, lse
.expr
,
3739 rse
.string_length
, rse
.expr
);
3740 gfc_add_expr_to_block (&se
->pre
, tmp
);
3742 /* Add the cleanup for the operands. */
3743 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
3744 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
3747 se
->string_length
= len
;
3750 /* Translates an op expression. Common (binary) cases are handled by this
3751 function, others are passed on. Recursion is used in either case.
3752 We use the fact that (op1.ts == op2.ts) (except for the power
3754 Operators need no special handling for scalarized expressions as long as
3755 they call gfc_conv_simple_val to get their operands.
3756 Character strings get special handling. */
3759 gfc_conv_expr_op (gfc_se
* se
, gfc_expr
* expr
)
3761 enum tree_code code
;
3770 switch (expr
->value
.op
.op
)
3772 case INTRINSIC_PARENTHESES
:
3773 if ((expr
->ts
.type
== BT_REAL
|| expr
->ts
.type
== BT_COMPLEX
)
3774 && flag_protect_parens
)
3776 gfc_conv_unary_op (PAREN_EXPR
, se
, expr
);
3777 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se
->expr
)));
3782 case INTRINSIC_UPLUS
:
3783 gfc_conv_expr (se
, expr
->value
.op
.op1
);
3786 case INTRINSIC_UMINUS
:
3787 gfc_conv_unary_op (NEGATE_EXPR
, se
, expr
);
3791 gfc_conv_unary_op (TRUTH_NOT_EXPR
, se
, expr
);
3794 case INTRINSIC_PLUS
:
3798 case INTRINSIC_MINUS
:
3802 case INTRINSIC_TIMES
:
3806 case INTRINSIC_DIVIDE
:
3807 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3808 an integer, we must round towards zero, so we use a
3810 if (expr
->ts
.type
== BT_INTEGER
)
3811 code
= TRUNC_DIV_EXPR
;
3816 case INTRINSIC_POWER
:
3817 gfc_conv_power_op (se
, expr
);
3820 case INTRINSIC_CONCAT
:
3821 gfc_conv_concat_op (se
, expr
);
3825 code
= flag_frontend_optimize
? TRUTH_ANDIF_EXPR
: TRUTH_AND_EXPR
;
3830 code
= flag_frontend_optimize
? TRUTH_ORIF_EXPR
: TRUTH_OR_EXPR
;
3834 /* EQV and NEQV only work on logicals, but since we represent them
3835 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3837 case INTRINSIC_EQ_OS
:
3845 case INTRINSIC_NE_OS
:
3846 case INTRINSIC_NEQV
:
3853 case INTRINSIC_GT_OS
:
3860 case INTRINSIC_GE_OS
:
3867 case INTRINSIC_LT_OS
:
3874 case INTRINSIC_LE_OS
:
3880 case INTRINSIC_USER
:
3881 case INTRINSIC_ASSIGN
:
3882 /* These should be converted into function calls by the frontend. */
3886 fatal_error (input_location
, "Unknown intrinsic op");
3890 /* The only exception to this is **, which is handled separately anyway. */
3891 gcc_assert (expr
->value
.op
.op1
->ts
.type
== expr
->value
.op
.op2
->ts
.type
);
3893 if (checkstring
&& expr
->value
.op
.op1
->ts
.type
!= BT_CHARACTER
)
3897 gfc_init_se (&lse
, se
);
3898 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
3899 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
3902 gfc_init_se (&rse
, se
);
3903 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
3904 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
3908 gfc_conv_string_parameter (&lse
);
3909 gfc_conv_string_parameter (&rse
);
3911 lse
.expr
= gfc_build_compare_string (lse
.string_length
, lse
.expr
,
3912 rse
.string_length
, rse
.expr
,
3913 expr
->value
.op
.op1
->ts
.kind
,
3915 rse
.expr
= build_int_cst (TREE_TYPE (lse
.expr
), 0);
3916 gfc_add_block_to_block (&lse
.post
, &rse
.post
);
3919 type
= gfc_typenode_for_spec (&expr
->ts
);
3923 /* The result of logical ops is always logical_type_node. */
3924 tmp
= fold_build2_loc (input_location
, code
, logical_type_node
,
3925 lse
.expr
, rse
.expr
);
3926 se
->expr
= convert (type
, tmp
);
3929 se
->expr
= fold_build2_loc (input_location
, code
, type
, lse
.expr
, rse
.expr
);
3931 /* Add the post blocks. */
3932 gfc_add_block_to_block (&se
->post
, &rse
.post
);
3933 gfc_add_block_to_block (&se
->post
, &lse
.post
);
3936 /* If a string's length is one, we convert it to a single character. */
3939 gfc_string_to_single_character (tree len
, tree str
, int kind
)
3943 || !tree_fits_uhwi_p (len
)
3944 || !POINTER_TYPE_P (TREE_TYPE (str
)))
3947 if (TREE_INT_CST_LOW (len
) == 1)
3949 str
= fold_convert (gfc_get_pchar_type (kind
), str
);
3950 return build_fold_indirect_ref_loc (input_location
, str
);
3954 && TREE_CODE (str
) == ADDR_EXPR
3955 && TREE_CODE (TREE_OPERAND (str
, 0)) == ARRAY_REF
3956 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str
, 0), 0)) == STRING_CST
3957 && array_ref_low_bound (TREE_OPERAND (str
, 0))
3958 == TREE_OPERAND (TREE_OPERAND (str
, 0), 1)
3959 && TREE_INT_CST_LOW (len
) > 1
3960 && TREE_INT_CST_LOW (len
)
3961 == (unsigned HOST_WIDE_INT
)
3962 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str
, 0), 0)))
3964 tree ret
= fold_convert (gfc_get_pchar_type (kind
), str
);
3965 ret
= build_fold_indirect_ref_loc (input_location
, ret
);
3966 if (TREE_CODE (ret
) == INTEGER_CST
)
3968 tree string_cst
= TREE_OPERAND (TREE_OPERAND (str
, 0), 0);
3969 int i
, length
= TREE_STRING_LENGTH (string_cst
);
3970 const char *ptr
= TREE_STRING_POINTER (string_cst
);
3972 for (i
= 1; i
< length
; i
++)
3985 conv_scalar_char_value (gfc_symbol
*sym
, gfc_se
*se
, gfc_expr
**expr
)
3989 /* We used to modify the tree here. Now it is done earlier in
3990 the front-end, so we only check it here to avoid regressions. */
3991 if (sym
->backend_decl
)
3993 gcc_assert (TREE_CODE (TREE_TYPE (sym
->backend_decl
)) == INTEGER_TYPE
);
3994 gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym
->backend_decl
)) == 1);
3995 gcc_assert (TYPE_PRECISION (TREE_TYPE (sym
->backend_decl
)) == CHAR_TYPE_SIZE
);
3996 gcc_assert (DECL_BY_REFERENCE (sym
->backend_decl
) == 0);
3999 /* If we have a constant character expression, make it into an
4000 integer of type C char. */
4001 if ((*expr
)->expr_type
== EXPR_CONSTANT
)
4006 *expr
= gfc_get_int_expr (gfc_default_character_kind
, NULL
,
4007 (*expr
)->value
.character
.string
[0]);
4009 else if (se
!= NULL
&& (*expr
)->expr_type
== EXPR_VARIABLE
)
4011 if ((*expr
)->ref
== NULL
)
4013 se
->expr
= gfc_string_to_single_character
4014 (build_int_cst (integer_type_node
, 1),
4015 gfc_build_addr_expr (gfc_get_pchar_type ((*expr
)->ts
.kind
),
4017 ((*expr
)->symtree
->n
.sym
)),
4022 gfc_conv_variable (se
, *expr
);
4023 se
->expr
= gfc_string_to_single_character
4024 (build_int_cst (integer_type_node
, 1),
4025 gfc_build_addr_expr (gfc_get_pchar_type ((*expr
)->ts
.kind
),
4032 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4033 if STR is a string literal, otherwise return -1. */
4036 gfc_optimize_len_trim (tree len
, tree str
, int kind
)
4039 && TREE_CODE (str
) == ADDR_EXPR
4040 && TREE_CODE (TREE_OPERAND (str
, 0)) == ARRAY_REF
4041 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str
, 0), 0)) == STRING_CST
4042 && array_ref_low_bound (TREE_OPERAND (str
, 0))
4043 == TREE_OPERAND (TREE_OPERAND (str
, 0), 1)
4044 && tree_fits_uhwi_p (len
)
4045 && tree_to_uhwi (len
) >= 1
4046 && tree_to_uhwi (len
)
4047 == (unsigned HOST_WIDE_INT
)
4048 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str
, 0), 0)))
4050 tree folded
= fold_convert (gfc_get_pchar_type (kind
), str
);
4051 folded
= build_fold_indirect_ref_loc (input_location
, folded
);
4052 if (TREE_CODE (folded
) == INTEGER_CST
)
4054 tree string_cst
= TREE_OPERAND (TREE_OPERAND (str
, 0), 0);
4055 int length
= TREE_STRING_LENGTH (string_cst
);
4056 const char *ptr
= TREE_STRING_POINTER (string_cst
);
4058 for (; length
> 0; length
--)
4059 if (ptr
[length
- 1] != ' ')
4068 /* Helper to build a call to memcmp. */
4071 build_memcmp_call (tree s1
, tree s2
, tree n
)
4075 if (!POINTER_TYPE_P (TREE_TYPE (s1
)))
4076 s1
= gfc_build_addr_expr (pvoid_type_node
, s1
);
4078 s1
= fold_convert (pvoid_type_node
, s1
);
4080 if (!POINTER_TYPE_P (TREE_TYPE (s2
)))
4081 s2
= gfc_build_addr_expr (pvoid_type_node
, s2
);
4083 s2
= fold_convert (pvoid_type_node
, s2
);
4085 n
= fold_convert (size_type_node
, n
);
4087 tmp
= build_call_expr_loc (input_location
,
4088 builtin_decl_explicit (BUILT_IN_MEMCMP
),
4091 return fold_convert (integer_type_node
, tmp
);
4094 /* Compare two strings. If they are all single characters, the result is the
4095 subtraction of them. Otherwise, we build a library call. */
4098 gfc_build_compare_string (tree len1
, tree str1
, tree len2
, tree str2
, int kind
,
4099 enum tree_code code
)
4105 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1
)));
4106 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2
)));
4108 sc1
= gfc_string_to_single_character (len1
, str1
, kind
);
4109 sc2
= gfc_string_to_single_character (len2
, str2
, kind
);
4111 if (sc1
!= NULL_TREE
&& sc2
!= NULL_TREE
)
4113 /* Deal with single character specially. */
4114 sc1
= fold_convert (integer_type_node
, sc1
);
4115 sc2
= fold_convert (integer_type_node
, sc2
);
4116 return fold_build2_loc (input_location
, MINUS_EXPR
, integer_type_node
,
4120 if ((code
== EQ_EXPR
|| code
== NE_EXPR
)
4122 && INTEGER_CST_P (len1
) && INTEGER_CST_P (len2
))
4124 /* If one string is a string literal with LEN_TRIM longer
4125 than the length of the second string, the strings
4127 int len
= gfc_optimize_len_trim (len1
, str1
, kind
);
4128 if (len
> 0 && compare_tree_int (len2
, len
) < 0)
4129 return integer_one_node
;
4130 len
= gfc_optimize_len_trim (len2
, str2
, kind
);
4131 if (len
> 0 && compare_tree_int (len1
, len
) < 0)
4132 return integer_one_node
;
4135 /* We can compare via memcpy if the strings are known to be equal
4136 in length and they are
4138 - kind=4 and the comparison is for (in)equality. */
4140 if (INTEGER_CST_P (len1
) && INTEGER_CST_P (len2
)
4141 && tree_int_cst_equal (len1
, len2
)
4142 && (kind
== 1 || code
== EQ_EXPR
|| code
== NE_EXPR
))
4147 chartype
= gfc_get_char_type (kind
);
4148 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE(len1
),
4149 fold_convert (TREE_TYPE(len1
),
4150 TYPE_SIZE_UNIT(chartype
)),
4152 return build_memcmp_call (str1
, str2
, tmp
);
4155 /* Build a call for the comparison. */
4157 fndecl
= gfor_fndecl_compare_string
;
4159 fndecl
= gfor_fndecl_compare_string_char4
;
4163 return build_call_expr_loc (input_location
, fndecl
, 4,
4164 len1
, str1
, len2
, str2
);
4168 /* Return the backend_decl for a procedure pointer component. */
4171 get_proc_ptr_comp (gfc_expr
*e
)
4177 gfc_init_se (&comp_se
, NULL
);
4178 e2
= gfc_copy_expr (e
);
4179 /* We have to restore the expr type later so that gfc_free_expr frees
4180 the exact same thing that was allocated.
4181 TODO: This is ugly. */
4182 old_type
= e2
->expr_type
;
4183 e2
->expr_type
= EXPR_VARIABLE
;
4184 gfc_conv_expr (&comp_se
, e2
);
4185 e2
->expr_type
= old_type
;
4187 return build_fold_addr_expr_loc (input_location
, comp_se
.expr
);
4191 /* Convert a typebound function reference from a class object. */
4193 conv_base_obj_fcn_val (gfc_se
* se
, tree base_object
, gfc_expr
* expr
)
4198 if (!VAR_P (base_object
))
4200 var
= gfc_create_var (TREE_TYPE (base_object
), NULL
);
4201 gfc_add_modify (&se
->pre
, var
, base_object
);
4203 se
->expr
= gfc_class_vptr_get (base_object
);
4204 se
->expr
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
4206 while (ref
&& ref
->next
)
4208 gcc_assert (ref
&& ref
->type
== REF_COMPONENT
);
4209 if (ref
->u
.c
.sym
->attr
.extension
)
4210 conv_parent_component_references (se
, ref
);
4211 gfc_conv_component_ref (se
, ref
);
4212 se
->expr
= build_fold_addr_expr_loc (input_location
, se
->expr
);
4217 conv_function_val (gfc_se
* se
, gfc_symbol
* sym
, gfc_expr
* expr
,
4218 gfc_actual_arglist
*actual_args
)
4222 if (gfc_is_proc_ptr_comp (expr
))
4223 tmp
= get_proc_ptr_comp (expr
);
4224 else if (sym
->attr
.dummy
)
4226 tmp
= gfc_get_symbol_decl (sym
);
4227 if (sym
->attr
.proc_pointer
)
4228 tmp
= build_fold_indirect_ref_loc (input_location
,
4230 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
4231 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) == FUNCTION_TYPE
);
4235 if (!sym
->backend_decl
)
4236 sym
->backend_decl
= gfc_get_extern_function_decl (sym
, actual_args
);
4238 TREE_USED (sym
->backend_decl
) = 1;
4240 tmp
= sym
->backend_decl
;
4242 if (sym
->attr
.cray_pointee
)
4244 /* TODO - make the cray pointee a pointer to a procedure,
4245 assign the pointer to it and use it for the call. This
4247 tmp
= convert (build_pointer_type (TREE_TYPE (tmp
)),
4248 gfc_get_symbol_decl (sym
->cp_pointer
));
4249 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
4252 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
4254 gcc_assert (TREE_CODE (tmp
) == FUNCTION_DECL
);
4255 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
4262 /* Initialize MAPPING. */
4265 gfc_init_interface_mapping (gfc_interface_mapping
* mapping
)
4267 mapping
->syms
= NULL
;
4268 mapping
->charlens
= NULL
;
4272 /* Free all memory held by MAPPING (but not MAPPING itself). */
4275 gfc_free_interface_mapping (gfc_interface_mapping
* mapping
)
4277 gfc_interface_sym_mapping
*sym
;
4278 gfc_interface_sym_mapping
*nextsym
;
4280 gfc_charlen
*nextcl
;
4282 for (sym
= mapping
->syms
; sym
; sym
= nextsym
)
4284 nextsym
= sym
->next
;
4285 sym
->new_sym
->n
.sym
->formal
= NULL
;
4286 gfc_free_symbol (sym
->new_sym
->n
.sym
);
4287 gfc_free_expr (sym
->expr
);
4288 free (sym
->new_sym
);
4291 for (cl
= mapping
->charlens
; cl
; cl
= nextcl
)
4294 gfc_free_expr (cl
->length
);
4300 /* Return a copy of gfc_charlen CL. Add the returned structure to
4301 MAPPING so that it will be freed by gfc_free_interface_mapping. */
4303 static gfc_charlen
*
4304 gfc_get_interface_mapping_charlen (gfc_interface_mapping
* mapping
,
4307 gfc_charlen
*new_charlen
;
4309 new_charlen
= gfc_get_charlen ();
4310 new_charlen
->next
= mapping
->charlens
;
4311 new_charlen
->length
= gfc_copy_expr (cl
->length
);
4313 mapping
->charlens
= new_charlen
;
4318 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4319 array variable that can be used as the actual argument for dummy
4320 argument SYM. Add any initialization code to BLOCK. PACKED is as
4321 for gfc_get_nodesc_array_type and DATA points to the first element
4322 in the passed array. */
4325 gfc_get_interface_mapping_array (stmtblock_t
* block
, gfc_symbol
* sym
,
4326 gfc_packed packed
, tree data
)
4331 type
= gfc_typenode_for_spec (&sym
->ts
);
4332 type
= gfc_get_nodesc_array_type (type
, sym
->as
, packed
,
4333 !sym
->attr
.target
&& !sym
->attr
.pointer
4334 && !sym
->attr
.proc_pointer
);
4336 var
= gfc_create_var (type
, "ifm");
4337 gfc_add_modify (block
, var
, fold_convert (type
, data
));
4343 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4344 and offset of descriptorless array type TYPE given that it has the same
4345 size as DESC. Add any set-up code to BLOCK. */
4348 gfc_set_interface_mapping_bounds (stmtblock_t
* block
, tree type
, tree desc
)
4355 offset
= gfc_index_zero_node
;
4356 for (n
= 0; n
< GFC_TYPE_ARRAY_RANK (type
); n
++)
4358 dim
= gfc_rank_cst
[n
];
4359 GFC_TYPE_ARRAY_STRIDE (type
, n
) = gfc_conv_array_stride (desc
, n
);
4360 if (GFC_TYPE_ARRAY_LBOUND (type
, n
) == NULL_TREE
)
4362 GFC_TYPE_ARRAY_LBOUND (type
, n
)
4363 = gfc_conv_descriptor_lbound_get (desc
, dim
);
4364 GFC_TYPE_ARRAY_UBOUND (type
, n
)
4365 = gfc_conv_descriptor_ubound_get (desc
, dim
);
4367 else if (GFC_TYPE_ARRAY_UBOUND (type
, n
) == NULL_TREE
)
4369 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4370 gfc_array_index_type
,
4371 gfc_conv_descriptor_ubound_get (desc
, dim
),
4372 gfc_conv_descriptor_lbound_get (desc
, dim
));
4373 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4374 gfc_array_index_type
,
4375 GFC_TYPE_ARRAY_LBOUND (type
, n
), tmp
);
4376 tmp
= gfc_evaluate_now (tmp
, block
);
4377 GFC_TYPE_ARRAY_UBOUND (type
, n
) = tmp
;
4379 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4380 GFC_TYPE_ARRAY_LBOUND (type
, n
),
4381 GFC_TYPE_ARRAY_STRIDE (type
, n
));
4382 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
4383 gfc_array_index_type
, offset
, tmp
);
4385 offset
= gfc_evaluate_now (offset
, block
);
4386 GFC_TYPE_ARRAY_OFFSET (type
) = offset
;
4390 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4391 in SE. The caller may still use se->expr and se->string_length after
4392 calling this function. */
4395 gfc_add_interface_mapping (gfc_interface_mapping
* mapping
,
4396 gfc_symbol
* sym
, gfc_se
* se
,
4399 gfc_interface_sym_mapping
*sm
;
4403 gfc_symbol
*new_sym
;
4405 gfc_symtree
*new_symtree
;
4407 /* Create a new symbol to represent the actual argument. */
4408 new_sym
= gfc_new_symbol (sym
->name
, NULL
);
4409 new_sym
->ts
= sym
->ts
;
4410 new_sym
->as
= gfc_copy_array_spec (sym
->as
);
4411 new_sym
->attr
.referenced
= 1;
4412 new_sym
->attr
.dimension
= sym
->attr
.dimension
;
4413 new_sym
->attr
.contiguous
= sym
->attr
.contiguous
;
4414 new_sym
->attr
.codimension
= sym
->attr
.codimension
;
4415 new_sym
->attr
.pointer
= sym
->attr
.pointer
;
4416 new_sym
->attr
.allocatable
= sym
->attr
.allocatable
;
4417 new_sym
->attr
.flavor
= sym
->attr
.flavor
;
4418 new_sym
->attr
.function
= sym
->attr
.function
;
4420 /* Ensure that the interface is available and that
4421 descriptors are passed for array actual arguments. */
4422 if (sym
->attr
.flavor
== FL_PROCEDURE
)
4424 new_sym
->formal
= expr
->symtree
->n
.sym
->formal
;
4425 new_sym
->attr
.always_explicit
4426 = expr
->symtree
->n
.sym
->attr
.always_explicit
;
4429 /* Create a fake symtree for it. */
4431 new_symtree
= gfc_new_symtree (&root
, sym
->name
);
4432 new_symtree
->n
.sym
= new_sym
;
4433 gcc_assert (new_symtree
== root
);
4435 /* Create a dummy->actual mapping. */
4436 sm
= XCNEW (gfc_interface_sym_mapping
);
4437 sm
->next
= mapping
->syms
;
4439 sm
->new_sym
= new_symtree
;
4440 sm
->expr
= gfc_copy_expr (expr
);
4443 /* Stabilize the argument's value. */
4444 if (!sym
->attr
.function
&& se
)
4445 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
4447 if (sym
->ts
.type
== BT_CHARACTER
)
4449 /* Create a copy of the dummy argument's length. */
4450 new_sym
->ts
.u
.cl
= gfc_get_interface_mapping_charlen (mapping
, sym
->ts
.u
.cl
);
4451 sm
->expr
->ts
.u
.cl
= new_sym
->ts
.u
.cl
;
4453 /* If the length is specified as "*", record the length that
4454 the caller is passing. We should use the callee's length
4455 in all other cases. */
4456 if (!new_sym
->ts
.u
.cl
->length
&& se
)
4458 se
->string_length
= gfc_evaluate_now (se
->string_length
, &se
->pre
);
4459 new_sym
->ts
.u
.cl
->backend_decl
= se
->string_length
;
4466 /* Use the passed value as-is if the argument is a function. */
4467 if (sym
->attr
.flavor
== FL_PROCEDURE
)
4470 /* If the argument is a pass-by-value scalar, use the value as is. */
4471 else if (!sym
->attr
.dimension
&& sym
->attr
.value
)
4474 /* If the argument is either a string or a pointer to a string,
4475 convert it to a boundless character type. */
4476 else if (!sym
->attr
.dimension
&& sym
->ts
.type
== BT_CHARACTER
)
4478 tmp
= gfc_get_character_type_len (sym
->ts
.kind
, NULL
);
4479 tmp
= build_pointer_type (tmp
);
4480 if (sym
->attr
.pointer
)
4481 value
= build_fold_indirect_ref_loc (input_location
,
4485 value
= fold_convert (tmp
, value
);
4488 /* If the argument is a scalar, a pointer to an array or an allocatable,
4490 else if (!sym
->attr
.dimension
|| sym
->attr
.pointer
|| sym
->attr
.allocatable
)
4491 value
= build_fold_indirect_ref_loc (input_location
,
4494 /* For character(*), use the actual argument's descriptor. */
4495 else if (sym
->ts
.type
== BT_CHARACTER
&& !new_sym
->ts
.u
.cl
->length
)
4496 value
= build_fold_indirect_ref_loc (input_location
,
4499 /* If the argument is an array descriptor, use it to determine
4500 information about the actual argument's shape. */
4501 else if (POINTER_TYPE_P (TREE_TYPE (se
->expr
))
4502 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se
->expr
))))
4504 /* Get the actual argument's descriptor. */
4505 desc
= build_fold_indirect_ref_loc (input_location
,
4508 /* Create the replacement variable. */
4509 tmp
= gfc_conv_descriptor_data_get (desc
);
4510 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
,
4513 /* Use DESC to work out the upper bounds, strides and offset. */
4514 gfc_set_interface_mapping_bounds (&se
->pre
, TREE_TYPE (value
), desc
);
4517 /* Otherwise we have a packed array. */
4518 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
,
4519 PACKED_FULL
, se
->expr
);
4521 new_sym
->backend_decl
= value
;
4525 /* Called once all dummy argument mappings have been added to MAPPING,
4526 but before the mapping is used to evaluate expressions. Pre-evaluate
4527 the length of each argument, adding any initialization code to PRE and
4528 any finalization code to POST. */
4531 gfc_finish_interface_mapping (gfc_interface_mapping
* mapping
,
4532 stmtblock_t
* pre
, stmtblock_t
* post
)
4534 gfc_interface_sym_mapping
*sym
;
4538 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
4539 if (sym
->new_sym
->n
.sym
->ts
.type
== BT_CHARACTER
4540 && !sym
->new_sym
->n
.sym
->ts
.u
.cl
->backend_decl
)
4542 expr
= sym
->new_sym
->n
.sym
->ts
.u
.cl
->length
;
4543 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
4544 gfc_init_se (&se
, NULL
);
4545 gfc_conv_expr (&se
, expr
);
4546 se
.expr
= fold_convert (gfc_charlen_type_node
, se
.expr
);
4547 se
.expr
= gfc_evaluate_now (se
.expr
, &se
.pre
);
4548 gfc_add_block_to_block (pre
, &se
.pre
);
4549 gfc_add_block_to_block (post
, &se
.post
);
4551 sym
->new_sym
->n
.sym
->ts
.u
.cl
->backend_decl
= se
.expr
;
4556 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4560 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping
* mapping
,
4561 gfc_constructor_base base
)
4564 for (c
= gfc_constructor_first (base
); c
; c
= gfc_constructor_next (c
))
4566 gfc_apply_interface_mapping_to_expr (mapping
, c
->expr
);
4569 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->start
);
4570 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->end
);
4571 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->step
);
4577 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4581 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping
* mapping
,
4586 for (; ref
; ref
= ref
->next
)
4590 for (n
= 0; n
< ref
->u
.ar
.dimen
; n
++)
4592 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.start
[n
]);
4593 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.end
[n
]);
4594 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.stride
[n
]);
4603 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.start
);
4604 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.end
);
4610 /* Convert intrinsic function calls into result expressions. */
4613 gfc_map_intrinsic_function (gfc_expr
*expr
, gfc_interface_mapping
*mapping
)
4621 arg1
= expr
->value
.function
.actual
->expr
;
4622 if (expr
->value
.function
.actual
->next
)
4623 arg2
= expr
->value
.function
.actual
->next
->expr
;
4627 sym
= arg1
->symtree
->n
.sym
;
4629 if (sym
->attr
.dummy
)
4634 switch (expr
->value
.function
.isym
->id
)
4637 /* TODO figure out why this condition is necessary. */
4638 if (sym
->attr
.function
4639 && (arg1
->ts
.u
.cl
->length
== NULL
4640 || (arg1
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
4641 && arg1
->ts
.u
.cl
->length
->expr_type
!= EXPR_VARIABLE
)))
4644 new_expr
= gfc_copy_expr (arg1
->ts
.u
.cl
->length
);
4647 case GFC_ISYM_LEN_TRIM
:
4648 new_expr
= gfc_copy_expr (arg1
);
4649 gfc_apply_interface_mapping_to_expr (mapping
, new_expr
);
4654 gfc_replace_expr (arg1
, new_expr
);
4658 if (!sym
->as
|| sym
->as
->rank
== 0)
4661 if (arg2
&& arg2
->expr_type
== EXPR_CONSTANT
)
4663 dup
= mpz_get_si (arg2
->value
.integer
);
4668 dup
= sym
->as
->rank
;
4672 for (; d
< dup
; d
++)
4676 if (!sym
->as
->upper
[d
] || !sym
->as
->lower
[d
])
4678 gfc_free_expr (new_expr
);
4682 tmp
= gfc_add (gfc_copy_expr (sym
->as
->upper
[d
]),
4683 gfc_get_int_expr (gfc_default_integer_kind
,
4685 tmp
= gfc_subtract (tmp
, gfc_copy_expr (sym
->as
->lower
[d
]));
4687 new_expr
= gfc_multiply (new_expr
, tmp
);
4693 case GFC_ISYM_LBOUND
:
4694 case GFC_ISYM_UBOUND
:
4695 /* TODO These implementations of lbound and ubound do not limit if
4696 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4698 if (!sym
->as
|| sym
->as
->rank
== 0)
4701 if (arg2
&& arg2
->expr_type
== EXPR_CONSTANT
)
4702 d
= mpz_get_si (arg2
->value
.integer
) - 1;
4706 if (expr
->value
.function
.isym
->id
== GFC_ISYM_LBOUND
)
4708 if (sym
->as
->lower
[d
])
4709 new_expr
= gfc_copy_expr (sym
->as
->lower
[d
]);
4713 if (sym
->as
->upper
[d
])
4714 new_expr
= gfc_copy_expr (sym
->as
->upper
[d
]);
4722 gfc_apply_interface_mapping_to_expr (mapping
, new_expr
);
4726 gfc_replace_expr (expr
, new_expr
);
4732 gfc_map_fcn_formal_to_actual (gfc_expr
*expr
, gfc_expr
*map_expr
,
4733 gfc_interface_mapping
* mapping
)
4735 gfc_formal_arglist
*f
;
4736 gfc_actual_arglist
*actual
;
4738 actual
= expr
->value
.function
.actual
;
4739 f
= gfc_sym_get_dummy_args (map_expr
->symtree
->n
.sym
);
4741 for (; f
&& actual
; f
= f
->next
, actual
= actual
->next
)
4746 gfc_add_interface_mapping (mapping
, f
->sym
, NULL
, actual
->expr
);
4749 if (map_expr
->symtree
->n
.sym
->attr
.dimension
)
4754 as
= gfc_copy_array_spec (map_expr
->symtree
->n
.sym
->as
);
4756 for (d
= 0; d
< as
->rank
; d
++)
4758 gfc_apply_interface_mapping_to_expr (mapping
, as
->lower
[d
]);
4759 gfc_apply_interface_mapping_to_expr (mapping
, as
->upper
[d
]);
4762 expr
->value
.function
.esym
->as
= as
;
4765 if (map_expr
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
)
4767 expr
->value
.function
.esym
->ts
.u
.cl
->length
4768 = gfc_copy_expr (map_expr
->symtree
->n
.sym
->ts
.u
.cl
->length
);
4770 gfc_apply_interface_mapping_to_expr (mapping
,
4771 expr
->value
.function
.esym
->ts
.u
.cl
->length
);
4776 /* EXPR is a copy of an expression that appeared in the interface
4777 associated with MAPPING. Walk it recursively looking for references to
4778 dummy arguments that MAPPING maps to actual arguments. Replace each such
4779 reference with a reference to the associated actual argument. */
4782 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
* mapping
,
4785 gfc_interface_sym_mapping
*sym
;
4786 gfc_actual_arglist
*actual
;
4791 /* Copying an expression does not copy its length, so do that here. */
4792 if (expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.u
.cl
)
4794 expr
->ts
.u
.cl
= gfc_get_interface_mapping_charlen (mapping
, expr
->ts
.u
.cl
);
4795 gfc_apply_interface_mapping_to_expr (mapping
, expr
->ts
.u
.cl
->length
);
4798 /* Apply the mapping to any references. */
4799 gfc_apply_interface_mapping_to_ref (mapping
, expr
->ref
);
4801 /* ...and to the expression's symbol, if it has one. */
4802 /* TODO Find out why the condition on expr->symtree had to be moved into
4803 the loop rather than being outside it, as originally. */
4804 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
4805 if (expr
->symtree
&& sym
->old
== expr
->symtree
->n
.sym
)
4807 if (sym
->new_sym
->n
.sym
->backend_decl
)
4808 expr
->symtree
= sym
->new_sym
;
4810 gfc_replace_expr (expr
, gfc_copy_expr (sym
->expr
));
4813 /* ...and to subexpressions in expr->value. */
4814 switch (expr
->expr_type
)
4819 case EXPR_SUBSTRING
:
4823 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op1
);
4824 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op2
);
4828 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
4829 gfc_apply_interface_mapping_to_expr (mapping
, actual
->expr
);
4831 if (expr
->value
.function
.esym
== NULL
4832 && expr
->value
.function
.isym
!= NULL
4833 && expr
->value
.function
.actual
4834 && expr
->value
.function
.actual
->expr
4835 && expr
->value
.function
.actual
->expr
->symtree
4836 && gfc_map_intrinsic_function (expr
, mapping
))
4839 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
4840 if (sym
->old
== expr
->value
.function
.esym
)
4842 expr
->value
.function
.esym
= sym
->new_sym
->n
.sym
;
4843 gfc_map_fcn_formal_to_actual (expr
, sym
->expr
, mapping
);
4844 expr
->value
.function
.esym
->result
= sym
->new_sym
->n
.sym
;
4849 case EXPR_STRUCTURE
:
4850 gfc_apply_interface_mapping_to_cons (mapping
, expr
->value
.constructor
);
4864 /* Evaluate interface expression EXPR using MAPPING. Store the result
4868 gfc_apply_interface_mapping (gfc_interface_mapping
* mapping
,
4869 gfc_se
* se
, gfc_expr
* expr
)
4871 expr
= gfc_copy_expr (expr
);
4872 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
4873 gfc_conv_expr (se
, expr
);
4874 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
4875 gfc_free_expr (expr
);
4879 /* Returns a reference to a temporary array into which a component of
4880 an actual argument derived type array is copied and then returned
4881 after the function call. */
4883 gfc_conv_subref_array_arg (gfc_se
*se
, gfc_expr
* expr
, int g77
,
4884 sym_intent intent
, bool formal_ptr
,
4885 const gfc_symbol
*fsym
, const char *proc_name
,
4886 gfc_symbol
*sym
, bool check_contiguous
)
4894 gfc_array_info
*info
;
4907 pass_optional
= fsym
&& fsym
->attr
.optional
&& sym
&& sym
->attr
.optional
;
4909 if (pass_optional
|| check_contiguous
)
4911 gfc_init_se (&work_se
, NULL
);
4917 if (gfc_option
.rtcheck
& GFC_RTCHECK_ARRAY_TEMPS
)
4919 /* We will create a temporary array, so let us warn. */
4922 if (fsym
&& proc_name
)
4923 msg
= xasprintf ("An array temporary was created for argument "
4924 "'%s' of procedure '%s'", fsym
->name
, proc_name
);
4926 msg
= xasprintf ("An array temporary was created");
4928 tmp
= build_int_cst (logical_type_node
, 1);
4929 gfc_trans_runtime_check (false, true, tmp
, &parmse
->pre
,
4934 gfc_init_se (&lse
, NULL
);
4935 gfc_init_se (&rse
, NULL
);
4937 /* Walk the argument expression. */
4938 rss
= gfc_walk_expr (expr
);
4940 gcc_assert (rss
!= gfc_ss_terminator
);
4942 /* Initialize the scalarizer. */
4943 gfc_init_loopinfo (&loop
);
4944 gfc_add_ss_to_loop (&loop
, rss
);
4946 /* Calculate the bounds of the scalarization. */
4947 gfc_conv_ss_startstride (&loop
);
4949 /* Build an ss for the temporary. */
4950 if (expr
->ts
.type
== BT_CHARACTER
&& !expr
->ts
.u
.cl
->backend_decl
)
4951 gfc_conv_string_length (expr
->ts
.u
.cl
, expr
, &parmse
->pre
);
4953 base_type
= gfc_typenode_for_spec (&expr
->ts
);
4954 if (GFC_ARRAY_TYPE_P (base_type
)
4955 || GFC_DESCRIPTOR_TYPE_P (base_type
))
4956 base_type
= gfc_get_element_type (base_type
);
4958 if (expr
->ts
.type
== BT_CLASS
)
4959 base_type
= gfc_typenode_for_spec (&CLASS_DATA (expr
)->ts
);
4961 loop
.temp_ss
= gfc_get_temp_ss (base_type
, ((expr
->ts
.type
== BT_CHARACTER
)
4962 ? expr
->ts
.u
.cl
->backend_decl
4966 parmse
->string_length
= loop
.temp_ss
->info
->string_length
;
4968 /* Associate the SS with the loop. */
4969 gfc_add_ss_to_loop (&loop
, loop
.temp_ss
);
4971 /* Setup the scalarizing loops. */
4972 gfc_conv_loop_setup (&loop
, &expr
->where
);
4974 /* Pass the temporary descriptor back to the caller. */
4975 info
= &loop
.temp_ss
->info
->data
.array
;
4976 parmse
->expr
= info
->descriptor
;
4978 /* Setup the gfc_se structures. */
4979 gfc_copy_loopinfo_to_se (&lse
, &loop
);
4980 gfc_copy_loopinfo_to_se (&rse
, &loop
);
4983 lse
.ss
= loop
.temp_ss
;
4984 gfc_mark_ss_chain_used (rss
, 1);
4985 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
4987 /* Start the scalarized loop body. */
4988 gfc_start_scalarized_body (&loop
, &body
);
4990 /* Translate the expression. */
4991 gfc_conv_expr (&rse
, expr
);
4993 /* Reset the offset for the function call since the loop
4994 is zero based on the data pointer. Note that the temp
4995 comes first in the loop chain since it is added second. */
4996 if (gfc_is_class_array_function (expr
))
4998 tmp
= loop
.ss
->loop_chain
->info
->data
.array
.descriptor
;
4999 gfc_conv_descriptor_offset_set (&loop
.pre
, tmp
,
5000 gfc_index_zero_node
);
5003 gfc_conv_tmp_array_ref (&lse
);
5005 if (intent
!= INTENT_OUT
)
5007 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, false, false);
5008 gfc_add_expr_to_block (&body
, tmp
);
5009 gcc_assert (rse
.ss
== gfc_ss_terminator
);
5010 gfc_trans_scalarizing_loops (&loop
, &body
);
5014 /* Make sure that the temporary declaration survives by merging
5015 all the loop declarations into the current context. */
5016 for (n
= 0; n
< loop
.dimen
; n
++)
5018 gfc_merge_block_scope (&body
);
5019 body
= loop
.code
[loop
.order
[n
]];
5021 gfc_merge_block_scope (&body
);
5024 /* Add the post block after the second loop, so that any
5025 freeing of allocated memory is done at the right time. */
5026 gfc_add_block_to_block (&parmse
->pre
, &loop
.pre
);
5028 /**********Copy the temporary back again.*********/
5030 gfc_init_se (&lse
, NULL
);
5031 gfc_init_se (&rse
, NULL
);
5033 /* Walk the argument expression. */
5034 lss
= gfc_walk_expr (expr
);
5035 rse
.ss
= loop
.temp_ss
;
5038 /* Initialize the scalarizer. */
5039 gfc_init_loopinfo (&loop2
);
5040 gfc_add_ss_to_loop (&loop2
, lss
);
5042 dimen
= rse
.ss
->dimen
;
5044 /* Skip the write-out loop for this case. */
5045 if (gfc_is_class_array_function (expr
))
5046 goto class_array_fcn
;
5048 /* Calculate the bounds of the scalarization. */
5049 gfc_conv_ss_startstride (&loop2
);
5051 /* Setup the scalarizing loops. */
5052 gfc_conv_loop_setup (&loop2
, &expr
->where
);
5054 gfc_copy_loopinfo_to_se (&lse
, &loop2
);
5055 gfc_copy_loopinfo_to_se (&rse
, &loop2
);
5057 gfc_mark_ss_chain_used (lss
, 1);
5058 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
5060 /* Declare the variable to hold the temporary offset and start the
5061 scalarized loop body. */
5062 offset
= gfc_create_var (gfc_array_index_type
, NULL
);
5063 gfc_start_scalarized_body (&loop2
, &body
);
5065 /* Build the offsets for the temporary from the loop variables. The
5066 temporary array has lbounds of zero and strides of one in all
5067 dimensions, so this is very simple. The offset is only computed
5068 outside the innermost loop, so the overall transfer could be
5069 optimized further. */
5070 info
= &rse
.ss
->info
->data
.array
;
5072 tmp_index
= gfc_index_zero_node
;
5073 for (n
= dimen
- 1; n
> 0; n
--)
5076 tmp
= rse
.loop
->loopvar
[n
];
5077 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
5078 tmp
, rse
.loop
->from
[n
]);
5079 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
5082 tmp_str
= fold_build2_loc (input_location
, MINUS_EXPR
,
5083 gfc_array_index_type
,
5084 rse
.loop
->to
[n
-1], rse
.loop
->from
[n
-1]);
5085 tmp_str
= fold_build2_loc (input_location
, PLUS_EXPR
,
5086 gfc_array_index_type
,
5087 tmp_str
, gfc_index_one_node
);
5089 tmp_index
= fold_build2_loc (input_location
, MULT_EXPR
,
5090 gfc_array_index_type
, tmp
, tmp_str
);
5093 tmp_index
= fold_build2_loc (input_location
, MINUS_EXPR
,
5094 gfc_array_index_type
,
5095 tmp_index
, rse
.loop
->from
[0]);
5096 gfc_add_modify (&rse
.loop
->code
[0], offset
, tmp_index
);
5098 tmp_index
= fold_build2_loc (input_location
, PLUS_EXPR
,
5099 gfc_array_index_type
,
5100 rse
.loop
->loopvar
[0], offset
);
5102 /* Now use the offset for the reference. */
5103 tmp
= build_fold_indirect_ref_loc (input_location
,
5105 rse
.expr
= gfc_build_array_ref (tmp
, tmp_index
, NULL
);
5107 if (expr
->ts
.type
== BT_CHARACTER
)
5108 rse
.string_length
= expr
->ts
.u
.cl
->backend_decl
;
5110 gfc_conv_expr (&lse
, expr
);
5112 gcc_assert (lse
.ss
== gfc_ss_terminator
);
5114 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, false, true);
5115 gfc_add_expr_to_block (&body
, tmp
);
5117 /* Generate the copying loops. */
5118 gfc_trans_scalarizing_loops (&loop2
, &body
);
5120 /* Wrap the whole thing up by adding the second loop to the post-block
5121 and following it by the post-block of the first loop. In this way,
5122 if the temporary needs freeing, it is done after use! */
5123 if (intent
!= INTENT_IN
)
5125 gfc_add_block_to_block (&parmse
->post
, &loop2
.pre
);
5126 gfc_add_block_to_block (&parmse
->post
, &loop2
.post
);
5131 gfc_add_block_to_block (&parmse
->post
, &loop
.post
);
5133 gfc_cleanup_loop (&loop
);
5134 gfc_cleanup_loop (&loop2
);
5136 /* Pass the string length to the argument expression. */
5137 if (expr
->ts
.type
== BT_CHARACTER
)
5138 parmse
->string_length
= expr
->ts
.u
.cl
->backend_decl
;
5140 /* Determine the offset for pointer formal arguments and set the
5144 size
= gfc_index_one_node
;
5145 offset
= gfc_index_zero_node
;
5146 for (n
= 0; n
< dimen
; n
++)
5148 tmp
= gfc_conv_descriptor_ubound_get (parmse
->expr
,
5150 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
5151 gfc_array_index_type
, tmp
,
5152 gfc_index_one_node
);
5153 gfc_conv_descriptor_ubound_set (&parmse
->pre
,
5157 gfc_conv_descriptor_lbound_set (&parmse
->pre
,
5160 gfc_index_one_node
);
5161 size
= gfc_evaluate_now (size
, &parmse
->pre
);
5162 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
5163 gfc_array_index_type
,
5165 offset
= gfc_evaluate_now (offset
, &parmse
->pre
);
5166 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
5167 gfc_array_index_type
,
5168 rse
.loop
->to
[n
], rse
.loop
->from
[n
]);
5169 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
5170 gfc_array_index_type
,
5171 tmp
, gfc_index_one_node
);
5172 size
= fold_build2_loc (input_location
, MULT_EXPR
,
5173 gfc_array_index_type
, size
, tmp
);
5176 gfc_conv_descriptor_offset_set (&parmse
->pre
, parmse
->expr
,
5180 /* We want either the address for the data or the address of the descriptor,
5181 depending on the mode of passing array arguments. */
5183 parmse
->expr
= gfc_conv_descriptor_data_get (parmse
->expr
);
5185 parmse
->expr
= gfc_build_addr_expr (NULL_TREE
, parmse
->expr
);
5187 /* Basically make this into
5198 pointer = parmse->expr;
5205 if (present && !contiguous)
5210 if (pass_optional
|| check_contiguous
)
5213 stmtblock_t else_block
;
5214 tree pre_stmts
, post_stmts
;
5217 tree present_var
= NULL_TREE
;
5218 tree cont_var
= NULL_TREE
;
5221 type
= TREE_TYPE (parmse
->expr
);
5222 if (POINTER_TYPE_P (type
) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type
)))
5223 type
= TREE_TYPE (type
);
5224 pointer
= gfc_create_var (type
, "arg_ptr");
5226 if (check_contiguous
)
5228 gfc_se cont_se
, array_se
;
5229 stmtblock_t if_block
, else_block
;
5230 tree if_stmt
, else_stmt
;
5234 cont_var
= gfc_create_var (boolean_type_node
, "contiguous");
5236 /* If the size is known to be one at compile-time, set
5237 cont_var to true unconditionally. This may look
5238 inelegant, but we're only doing this during
5239 optimization, so the statements will be optimized away,
5240 and this saves complexity here. */
5242 size_set
= gfc_array_size (expr
, &size
);
5243 if (size_set
&& mpz_cmp_ui (size
, 1) == 0)
5245 gfc_add_modify (&se
->pre
, cont_var
,
5246 build_one_cst (boolean_type_node
));
5250 /* cont_var = is_contiguous (expr); . */
5251 gfc_init_se (&cont_se
, parmse
);
5252 gfc_conv_is_contiguous_expr (&cont_se
, expr
);
5253 gfc_add_block_to_block (&se
->pre
, &(&cont_se
)->pre
);
5254 gfc_add_modify (&se
->pre
, cont_var
, cont_se
.expr
);
5255 gfc_add_block_to_block (&se
->pre
, &(&cont_se
)->post
);
5261 /* arrayse->expr = descriptor of a. */
5262 gfc_init_se (&array_se
, se
);
5263 gfc_conv_expr_descriptor (&array_se
, expr
);
5264 gfc_add_block_to_block (&se
->pre
, &(&array_se
)->pre
);
5265 gfc_add_block_to_block (&se
->pre
, &(&array_se
)->post
);
5267 /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } . */
5268 gfc_init_block (&if_block
);
5269 if (GFC_DESCRIPTOR_TYPE_P (type
))
5270 gfc_add_modify (&if_block
, pointer
, array_se
.expr
);
5273 tmp
= gfc_conv_array_data (array_se
.expr
);
5274 tmp
= fold_convert (type
, tmp
);
5275 gfc_add_modify (&if_block
, pointer
, tmp
);
5277 if_stmt
= gfc_finish_block (&if_block
);
5279 /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5280 gfc_init_block (&else_block
);
5281 gfc_add_block_to_block (&else_block
, &parmse
->pre
);
5282 tmp
= (GFC_DESCRIPTOR_TYPE_P (type
)
5283 ? build_fold_indirect_ref_loc (input_location
, parmse
->expr
)
5285 gfc_add_modify (&else_block
, pointer
, tmp
);
5286 else_stmt
= gfc_finish_block (&else_block
);
5288 /* And put the above into an if statement. */
5289 pre_stmts
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
5290 gfc_likely (cont_var
,
5291 PRED_FORTRAN_CONTIGUOUS
),
5292 if_stmt
, else_stmt
);
5296 /* pointer = pramse->expr; . */
5297 gfc_add_modify (&parmse
->pre
, pointer
, parmse
->expr
);
5298 pre_stmts
= gfc_finish_block (&parmse
->pre
);
5303 present_var
= gfc_create_var (boolean_type_node
, "present");
5305 /* present_var = present(sym); . */
5306 tmp
= gfc_conv_expr_present (sym
);
5307 tmp
= fold_convert (boolean_type_node
, tmp
);
5308 gfc_add_modify (&se
->pre
, present_var
, tmp
);
5310 /* else_stmt = { pointer = NULL; } . */
5311 gfc_init_block (&else_block
);
5312 if (GFC_DESCRIPTOR_TYPE_P (type
))
5313 gfc_conv_descriptor_data_set (&else_block
, pointer
,
5316 gfc_add_modify (&else_block
, pointer
, build_int_cst (type
, 0));
5317 else_stmt
= gfc_finish_block (&else_block
);
5319 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
5320 gfc_likely (present_var
,
5321 PRED_FORTRAN_ABSENT_DUMMY
),
5322 pre_stmts
, else_stmt
);
5323 gfc_add_expr_to_block (&se
->pre
, tmp
);
5326 gfc_add_expr_to_block (&se
->pre
, pre_stmts
);
5328 post_stmts
= gfc_finish_block (&parmse
->post
);
5330 /* Put together the post stuff, plus the optional
5332 if (check_contiguous
)
5335 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
5337 build_zero_cst (boolean_type_node
));
5338 tmp
= gfc_unlikely (tmp
, PRED_FORTRAN_CONTIGUOUS
);
5342 tree present_likely
= gfc_likely (present_var
,
5343 PRED_FORTRAN_ABSENT_DUMMY
);
5344 post_cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
5345 boolean_type_node
, present_likely
,
5353 gcc_assert (pass_optional
);
5354 post_cond
= present_var
;
5357 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, post_cond
,
5358 post_stmts
, build_empty_stmt (input_location
));
5359 gfc_add_expr_to_block (&se
->post
, tmp
);
5360 if (GFC_DESCRIPTOR_TYPE_P (type
))
5362 type
= TREE_TYPE (parmse
->expr
);
5363 if (POINTER_TYPE_P (type
))
5365 pointer
= gfc_build_addr_expr (type
, pointer
);
5368 tmp
= gfc_likely (present_var
, PRED_FORTRAN_ABSENT_DUMMY
);
5369 pointer
= fold_build3_loc (input_location
, COND_EXPR
, type
,
5372 null_pointer_node
));
5376 gcc_assert (!pass_optional
);
5385 /* Generate the code for argument list functions. */
5388 conv_arglist_function (gfc_se
*se
, gfc_expr
*expr
, const char *name
)
5390 /* Pass by value for g77 %VAL(arg), pass the address
5391 indirectly for %LOC, else by reference. Thus %REF
5392 is a "do-nothing" and %LOC is the same as an F95
5394 if (strcmp (name
, "%VAL") == 0)
5395 gfc_conv_expr (se
, expr
);
5396 else if (strcmp (name
, "%LOC") == 0)
5398 gfc_conv_expr_reference (se
, expr
);
5399 se
->expr
= gfc_build_addr_expr (NULL
, se
->expr
);
5401 else if (strcmp (name
, "%REF") == 0)
5402 gfc_conv_expr_reference (se
, expr
);
5404 gfc_error ("Unknown argument list function at %L", &expr
->where
);
5408 /* This function tells whether the middle-end representation of the expression
5409 E given as input may point to data otherwise accessible through a variable
5411 It is assumed that the only expressions that may alias are variables,
5412 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5414 This function is used to decide whether freeing an expression's allocatable
5415 components is safe or should be avoided.
5417 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5418 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5419 is necessary because for array constructors, aliasing depends on how
5421 - If E is an array constructor used as argument to an elemental procedure,
5422 the array, which is generated through shallow copy by the scalarizer,
5423 is used directly and can alias the expressions it was copied from.
5424 - If E is an array constructor used as argument to a non-elemental
5425 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5426 the array as in the previous case, but then that array is used
5427 to initialize a new descriptor through deep copy. There is no alias
5428 possible in that case.
5429 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5433 expr_may_alias_variables (gfc_expr
*e
, bool array_may_alias
)
5437 if (e
->expr_type
== EXPR_VARIABLE
)
5439 else if (e
->expr_type
== EXPR_FUNCTION
)
5441 gfc_symbol
*proc_ifc
= gfc_get_proc_ifc_for_expr (e
);
5443 if (proc_ifc
->result
!= NULL
5444 && ((proc_ifc
->result
->ts
.type
== BT_CLASS
5445 && proc_ifc
->result
->ts
.u
.derived
->attr
.is_class
5446 && CLASS_DATA (proc_ifc
->result
)->attr
.class_pointer
)
5447 || proc_ifc
->result
->attr
.pointer
))
5452 else if (e
->expr_type
!= EXPR_ARRAY
|| !array_may_alias
)
5455 for (c
= gfc_constructor_first (e
->value
.constructor
);
5456 c
; c
= gfc_constructor_next (c
))
5458 && expr_may_alias_variables (c
->expr
, array_may_alias
))
5465 /* A helper function to set the dtype for unallocated or unassociated
5469 set_dtype_for_unallocated (gfc_se
*parmse
, gfc_expr
*e
)
5477 /* TODO Figure out how to handle optional dummies. */
5478 if (e
&& e
->expr_type
== EXPR_VARIABLE
5479 && e
->symtree
->n
.sym
->attr
.optional
)
5482 desc
= parmse
->expr
;
5483 if (desc
== NULL_TREE
)
5486 if (POINTER_TYPE_P (TREE_TYPE (desc
)))
5487 desc
= build_fold_indirect_ref_loc (input_location
, desc
);
5488 if (GFC_CLASS_TYPE_P (TREE_TYPE (desc
)))
5489 desc
= gfc_class_data_get (desc
);
5490 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc
)))
5493 gfc_init_block (&block
);
5494 tmp
= gfc_conv_descriptor_data_get (desc
);
5495 cond
= fold_build2_loc (input_location
, EQ_EXPR
,
5496 logical_type_node
, tmp
,
5497 build_int_cst (TREE_TYPE (tmp
), 0));
5498 tmp
= gfc_conv_descriptor_dtype (desc
);
5499 type
= gfc_get_element_type (TREE_TYPE (desc
));
5500 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
5501 TREE_TYPE (tmp
), tmp
,
5502 gfc_get_dtype_rank_type (e
->rank
, type
));
5503 gfc_add_expr_to_block (&block
, tmp
);
5504 cond
= build3_v (COND_EXPR
, cond
,
5505 gfc_finish_block (&block
),
5506 build_empty_stmt (input_location
));
5507 gfc_add_expr_to_block (&parmse
->pre
, cond
);
5512 /* Provide an interface between gfortran array descriptors and the F2018:18.4
5513 ISO_Fortran_binding array descriptors. */
5516 gfc_conv_gfc_desc_to_cfi_desc (gfc_se
*parmse
, gfc_expr
*e
, gfc_symbol
*fsym
)
5518 stmtblock_t block
, block2
;
5519 tree cfi
, gfc
, tmp
, tmp2
;
5520 tree present
= NULL
;
5521 tree gfc_strlen
= NULL
;
5525 if (fsym
->attr
.optional
5526 && e
->expr_type
== EXPR_VARIABLE
5527 && e
->symtree
->n
.sym
->attr
.optional
)
5528 present
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
5530 gfc_init_block (&block
);
5532 /* Convert original argument to a tree. */
5533 gfc_init_se (&se
, NULL
);
5536 se
.want_pointer
= 1;
5537 gfc_conv_expr (&se
, e
);
5539 /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */
5540 if (!POINTER_TYPE_P (TREE_TYPE (gfc
)))
5541 gfc
= gfc_build_addr_expr (NULL
, gfc
);
5545 /* If the actual argument can be noncontiguous, copy-in/out is required,
5546 if the dummy has either the CONTIGUOUS attribute or is an assumed-
5547 length assumed-length/assumed-size CHARACTER array. This only
5548 applies if the actual argument is a "variable"; if it's some
5549 non-lvalue expression, we are going to evaluate it to a
5550 temporary below anyway. */
5551 se
.force_no_tmp
= 1;
5552 if ((fsym
->attr
.contiguous
5553 || (fsym
->ts
.type
== BT_CHARACTER
&& !fsym
->ts
.u
.cl
->length
5554 && (fsym
->as
->type
== AS_ASSUMED_SIZE
5555 || fsym
->as
->type
== AS_EXPLICIT
)))
5556 && !gfc_is_simply_contiguous (e
, false, true)
5557 && gfc_expr_is_variable (e
))
5559 bool optional
= fsym
->attr
.optional
;
5560 fsym
->attr
.optional
= 0;
5561 gfc_conv_subref_array_arg (&se
, e
, false, fsym
->attr
.intent
,
5562 fsym
->attr
.pointer
, fsym
,
5563 fsym
->ns
->proc_name
->name
, NULL
,
5564 /* check_contiguous= */ true);
5565 fsym
->attr
.optional
= optional
;
5568 gfc_conv_expr_descriptor (&se
, e
);
5570 /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
5571 elem_len = sizeof(dt) and base_addr = dt(lb) instead.
5572 gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
5573 While sm is fine as it uses span*stride and not elem_len. */
5574 if (POINTER_TYPE_P (TREE_TYPE (gfc
)))
5575 gfc
= build_fold_indirect_ref_loc (input_location
, gfc
);
5576 else if (is_subref_array (e
) && e
->ts
.type
!= BT_CHARACTER
)
5577 gfc_get_dataptr_offset (&se
.pre
, gfc
, gfc
, NULL
, true, e
);
5579 if (e
->ts
.type
== BT_CHARACTER
)
5581 if (se
.string_length
)
5582 gfc_strlen
= se
.string_length
;
5583 else if (e
->ts
.u
.cl
->backend_decl
)
5584 gfc_strlen
= e
->ts
.u
.cl
->backend_decl
;
5588 gfc_add_block_to_block (&block
, &se
.pre
);
5590 /* Create array decriptor and set version, rank, attribute, type. */
5591 cfi
= gfc_create_var (gfc_get_cfi_type (e
->rank
< 0
5592 ? GFC_MAX_DIMENSIONS
: e
->rank
,
5594 /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
5595 if (fsym
->attr
.dimension
&& fsym
->as
->type
== AS_ASSUMED_RANK
)
5597 tmp
= gfc_get_cfi_type (-1, !fsym
->attr
.pointer
&& !fsym
->attr
.target
);
5598 tmp
= build_pointer_type (tmp
);
5599 parmse
->expr
= cfi
= gfc_build_addr_expr (tmp
, cfi
);
5600 cfi
= build_fold_indirect_ref_loc (input_location
, cfi
);
5603 parmse
->expr
= gfc_build_addr_expr (NULL
, cfi
);
5605 tmp
= gfc_get_cfi_desc_version (cfi
);
5606 gfc_add_modify (&block
, tmp
,
5607 build_int_cst (TREE_TYPE (tmp
), CFI_VERSION
));
5609 rank
= fold_convert (signed_char_type_node
, gfc_conv_descriptor_rank (gfc
));
5611 rank
= build_int_cst (signed_char_type_node
, e
->rank
);
5612 tmp
= gfc_get_cfi_desc_rank (cfi
);
5613 gfc_add_modify (&block
, tmp
, rank
);
5614 int itype
= CFI_type_other
;
5615 if (e
->ts
.f90_type
== BT_VOID
)
5616 itype
= (e
->ts
.u
.derived
->intmod_sym_id
== ISOCBINDING_FUNPTR
5617 ? CFI_type_cfunptr
: CFI_type_cptr
);
5620 if (e
->expr_type
== EXPR_NULL
&& e
->ts
.type
== BT_UNKNOWN
)
5628 itype
= CFI_type_from_type_kind (e
->ts
.type
, e
->ts
.kind
);
5631 itype
= CFI_type_from_type_kind (CFI_type_Character
, e
->ts
.kind
);
5634 itype
= CFI_type_struct
;
5637 itype
= (e
->ts
.u
.derived
->intmod_sym_id
== ISOCBINDING_FUNPTR
5638 ? CFI_type_cfunptr
: CFI_type_cptr
);
5641 itype
= CFI_type_other
; // FIXME: Or CFI_type_cptr ?
5644 if (UNLIMITED_POLY (e
) && fsym
->ts
.type
== BT_ASSUMED
)
5646 // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
5647 // type specifier is assumed-type and is an unlimited polymorphic
5648 // entity." The actual argument _data component is passed.
5649 itype
= CFI_type_other
; // FIXME: Or CFI_type_cptr ?
5659 // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
5664 tmp
= gfc_get_cfi_desc_type (cfi
);
5665 gfc_add_modify (&block
, tmp
,
5666 build_int_cst (TREE_TYPE (tmp
), itype
));
5668 int attr
= CFI_attribute_other
;
5669 if (fsym
->attr
.pointer
)
5670 attr
= CFI_attribute_pointer
;
5671 else if (fsym
->attr
.allocatable
)
5672 attr
= CFI_attribute_allocatable
;
5673 tmp
= gfc_get_cfi_desc_attribute (cfi
);
5674 gfc_add_modify (&block
, tmp
,
5675 build_int_cst (TREE_TYPE (tmp
), attr
));
5677 /* The cfi-base_addr assignment could be skipped for 'pointer, intent(out)'.
5678 That is very sensible for undefined pointers, but the C code might assume
5679 that the pointer retains the value, in particular, if it was NULL. */
5682 tmp
= gfc_get_cfi_desc_base_addr (cfi
);
5683 gfc_add_modify (&block
, tmp
, fold_convert (TREE_TYPE (tmp
), gfc
));
5687 tmp
= gfc_get_cfi_desc_base_addr (cfi
);
5688 tmp2
= gfc_conv_descriptor_data_get (gfc
);
5689 gfc_add_modify (&block
, tmp
, fold_convert (TREE_TYPE (tmp
), tmp2
));
5692 /* Set elem_len if known - must be before the next if block.
5693 Note that allocatable implies 'len=:'. */
5694 if (e
->ts
.type
!= BT_ASSUMED
&& e
->ts
.type
!= BT_CHARACTER
)
5696 /* Length is known at compile time; use 'block' for it. */
5697 tmp
= size_in_bytes (gfc_typenode_for_spec (&e
->ts
));
5698 tmp2
= gfc_get_cfi_desc_elem_len (cfi
);
5699 gfc_add_modify (&block
, tmp2
, fold_convert (TREE_TYPE (tmp2
), tmp
));
5702 if (fsym
->attr
.pointer
&& fsym
->attr
.intent
== INTENT_OUT
)
5705 /* When allocatable + intent out, free the cfi descriptor. */
5706 if (fsym
->attr
.allocatable
&& fsym
->attr
.intent
== INTENT_OUT
)
5708 tmp
= gfc_get_cfi_desc_base_addr (cfi
);
5709 tree call
= builtin_decl_explicit (BUILT_IN_FREE
);
5710 call
= build_call_expr_loc (input_location
, call
, 1, tmp
);
5711 gfc_add_expr_to_block (&block
, fold_convert (void_type_node
, call
));
5712 gfc_add_modify (&block
, tmp
,
5713 fold_convert (TREE_TYPE (tmp
), null_pointer_node
));
5717 /* If not unallocated/unassociated. */
5718 gfc_init_block (&block2
);
5720 /* Set elem_len, which may be only known at run time. */
5721 if (e
->ts
.type
== BT_CHARACTER
5722 && (e
->expr_type
!= EXPR_NULL
|| gfc_strlen
!= NULL_TREE
))
5724 gcc_assert (gfc_strlen
);
5726 if (e
->ts
.kind
!= 1)
5727 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
5728 gfc_charlen_type_node
, tmp
,
5729 build_int_cst (gfc_charlen_type_node
,
5731 tmp2
= gfc_get_cfi_desc_elem_len (cfi
);
5732 gfc_add_modify (&block2
, tmp2
, fold_convert (TREE_TYPE (tmp2
), tmp
));
5734 else if (e
->ts
.type
== BT_ASSUMED
)
5736 tmp
= gfc_conv_descriptor_elem_len (gfc
);
5737 tmp2
= gfc_get_cfi_desc_elem_len (cfi
);
5738 gfc_add_modify (&block2
, tmp2
, fold_convert (TREE_TYPE (tmp2
), tmp
));
5741 if (e
->ts
.type
== BT_ASSUMED
)
5743 /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
5744 an CFI descriptor. Use the type in the descritor as it provide
5745 mode information. (Quality of implementation feature.) */
5747 tree ctype
= gfc_get_cfi_desc_type (cfi
);
5748 tree type
= fold_convert (TREE_TYPE (ctype
),
5749 gfc_conv_descriptor_type (gfc
));
5750 tree kind
= fold_convert (TREE_TYPE (ctype
),
5751 gfc_conv_descriptor_elem_len (gfc
));
5752 kind
= fold_build2_loc (input_location
, LSHIFT_EXPR
, TREE_TYPE (type
),
5753 kind
, build_int_cst (TREE_TYPE (type
),
5754 CFI_type_kind_shift
));
5756 /* if (BT_VOID) CFI_type_cptr else CFI_type_other */
5757 /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
5758 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5759 build_int_cst (TREE_TYPE (type
), BT_VOID
));
5760 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
, ctype
,
5761 build_int_cst (TREE_TYPE (type
), CFI_type_cptr
));
5762 tmp2
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
5764 build_int_cst (TREE_TYPE (type
), CFI_type_other
));
5765 tmp2
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5767 /* if (BT_DERIVED) CFI_type_struct else < tmp2 > */
5768 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5769 build_int_cst (TREE_TYPE (type
), BT_DERIVED
));
5770 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
, ctype
,
5771 build_int_cst (TREE_TYPE (type
), CFI_type_struct
));
5772 tmp2
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5774 /* if (BT_CHARACTER) CFI_type_Character + kind=1 else < tmp2 > */
5775 /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4. */
5776 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5777 build_int_cst (TREE_TYPE (type
), BT_CHARACTER
));
5778 tmp
= build_int_cst (TREE_TYPE (type
),
5779 CFI_type_from_type_kind (CFI_type_Character
, 1));
5780 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
5782 tmp2
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5784 /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else < tmp2 > */
5785 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5786 build_int_cst (TREE_TYPE (type
), BT_COMPLEX
));
5787 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
, TREE_TYPE (type
),
5788 kind
, build_int_cst (TREE_TYPE (type
), 2));
5789 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (type
), tmp
,
5790 build_int_cst (TREE_TYPE (type
),
5792 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
5794 tmp2
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5796 /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else <tmp2> */
5797 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5798 build_int_cst (TREE_TYPE (type
), BT_INTEGER
));
5799 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5800 build_int_cst (TREE_TYPE (type
), BT_LOGICAL
));
5801 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
, boolean_type_node
,
5803 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, type
,
5804 build_int_cst (TREE_TYPE (type
), BT_REAL
));
5805 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
, boolean_type_node
,
5807 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (type
),
5809 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
5811 tmp2
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
5813 gfc_add_expr_to_block (&block2
, tmp2
);
5818 /* Loop: for (i = 0; i < rank; ++i). */
5819 tree idx
= gfc_create_var (TREE_TYPE (rank
), "idx");
5821 stmtblock_t loop_body
;
5822 gfc_init_block (&loop_body
);
5823 /* cfi->dim[i].lower_bound = (allocatable/pointer)
5824 ? gfc->dim[i].lbound : 0 */
5825 if (fsym
->attr
.pointer
|| fsym
->attr
.allocatable
)
5826 tmp
= gfc_conv_descriptor_lbound_get (gfc
, idx
);
5828 tmp
= gfc_index_zero_node
;
5829 gfc_add_modify (&loop_body
, gfc_get_cfi_dim_lbound (cfi
, idx
), tmp
);
5830 /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
5831 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
5832 gfc_conv_descriptor_ubound_get (gfc
, idx
),
5833 gfc_conv_descriptor_lbound_get (gfc
, idx
));
5834 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
5835 tmp
, gfc_index_one_node
);
5836 gfc_add_modify (&loop_body
, gfc_get_cfi_dim_extent (cfi
, idx
), tmp
);
5837 /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
5838 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
5839 gfc_conv_descriptor_stride_get (gfc
, idx
),
5840 gfc_conv_descriptor_span_get (gfc
));
5841 gfc_add_modify (&loop_body
, gfc_get_cfi_dim_sm (cfi
, idx
), tmp
);
5843 /* Generate loop. */
5844 gfc_simple_for_loop (&block2
, idx
, build_int_cst (TREE_TYPE (idx
), 0),
5845 rank
, LT_EXPR
, build_int_cst (TREE_TYPE (idx
), 1),
5846 gfc_finish_block (&loop_body
));
5848 if (e
->expr_type
== EXPR_VARIABLE
5850 && e
->ref
->u
.ar
.type
== AR_FULL
5851 && e
->symtree
->n
.sym
->attr
.dummy
5852 && e
->symtree
->n
.sym
->as
5853 && e
->symtree
->n
.sym
->as
->type
== AS_ASSUMED_SIZE
)
5855 tmp
= gfc_get_cfi_dim_extent (cfi
, gfc_rank_cst
[e
->rank
-1]),
5856 gfc_add_modify (&block2
, tmp
, build_int_cst (TREE_TYPE (tmp
), -1));
5860 if (fsym
->attr
.allocatable
|| fsym
->attr
.pointer
)
5862 tmp
= gfc_get_cfi_desc_base_addr (cfi
),
5863 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
5864 tmp
, null_pointer_node
);
5865 tmp
= build3_v (COND_EXPR
, tmp
, gfc_finish_block (&block2
),
5866 build_empty_stmt (input_location
));
5867 gfc_add_expr_to_block (&block
, tmp
);
5870 gfc_add_block_to_block (&block
, &block2
);
5876 parmse
->expr
= build3_loc (input_location
, COND_EXPR
,
5877 TREE_TYPE (parmse
->expr
),
5878 present
, parmse
->expr
, null_pointer_node
);
5879 tmp
= build3_v (COND_EXPR
, present
, gfc_finish_block (&block
),
5880 build_empty_stmt (input_location
));
5881 gfc_add_expr_to_block (&parmse
->pre
, tmp
);
5884 gfc_add_block_to_block (&parmse
->pre
, &block
);
5886 gfc_init_block (&block
);
5888 if ((!fsym
->attr
.allocatable
&& !fsym
->attr
.pointer
)
5889 || fsym
->attr
.intent
== INTENT_IN
)
5892 gfc_init_block (&block2
);
5895 tmp
= gfc_get_cfi_desc_base_addr (cfi
);
5896 gfc_add_modify (&block
, gfc
, fold_convert (TREE_TYPE (gfc
), tmp
));
5900 tmp
= gfc_get_cfi_desc_base_addr (cfi
);
5901 gfc_conv_descriptor_data_set (&block
, gfc
, tmp
);
5903 if (fsym
->attr
.allocatable
)
5905 /* gfc->span = cfi->elem_len. */
5906 tmp
= fold_convert (gfc_array_index_type
,
5907 gfc_get_cfi_dim_sm (cfi
, gfc_rank_cst
[0]));
5911 /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
5912 ? cfi->dim[0].sm : cfi->elem_len). */
5913 tmp
= gfc_get_cfi_dim_sm (cfi
, gfc_rank_cst
[0]);
5914 tmp2
= fold_convert (gfc_array_index_type
,
5915 gfc_get_cfi_desc_elem_len (cfi
));
5916 tmp
= fold_build2_loc (input_location
, TRUNC_MOD_EXPR
,
5917 gfc_array_index_type
, tmp
, tmp2
);
5918 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
5919 tmp
, gfc_index_zero_node
);
5920 tmp
= build3_loc (input_location
, COND_EXPR
, gfc_array_index_type
, tmp
,
5921 gfc_get_cfi_dim_sm (cfi
, gfc_rank_cst
[0]), tmp2
);
5923 gfc_conv_descriptor_span_set (&block2
, gfc
, tmp
);
5925 /* Calculate offset + set lbound, ubound and stride. */
5926 gfc_conv_descriptor_offset_set (&block2
, gfc
, gfc_index_zero_node
);
5927 /* Loop: for (i = 0; i < rank; ++i). */
5928 tree idx
= gfc_create_var (TREE_TYPE (rank
), "idx");
5930 stmtblock_t loop_body
;
5931 gfc_init_block (&loop_body
);
5932 /* gfc->dim[i].lbound = ... */
5933 tmp
= gfc_get_cfi_dim_lbound (cfi
, idx
);
5934 gfc_conv_descriptor_lbound_set (&loop_body
, gfc
, idx
, tmp
);
5936 /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
5937 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
5938 gfc_conv_descriptor_lbound_get (gfc
, idx
),
5939 gfc_index_one_node
);
5940 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
5941 gfc_get_cfi_dim_extent (cfi
, idx
), tmp
);
5942 gfc_conv_descriptor_ubound_set (&loop_body
, gfc
, idx
, tmp
);
5944 /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
5945 tmp
= gfc_get_cfi_dim_sm (cfi
, idx
);
5946 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
5947 gfc_array_index_type
, tmp
,
5948 fold_convert (gfc_array_index_type
,
5949 gfc_get_cfi_desc_elem_len (cfi
)));
5950 gfc_conv_descriptor_stride_set (&loop_body
, gfc
, idx
, tmp
);
5952 /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
5953 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
5954 gfc_conv_descriptor_stride_get (gfc
, idx
),
5955 gfc_conv_descriptor_lbound_get (gfc
, idx
));
5956 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
5957 gfc_conv_descriptor_offset_get (gfc
), tmp
);
5958 gfc_conv_descriptor_offset_set (&loop_body
, gfc
, tmp
);
5959 /* Generate loop. */
5960 gfc_simple_for_loop (&block2
, idx
, build_int_cst (TREE_TYPE (idx
), 0),
5961 rank
, LT_EXPR
, build_int_cst (TREE_TYPE (idx
), 1),
5962 gfc_finish_block (&loop_body
));
5965 if (e
->ts
.type
== BT_CHARACTER
&& !e
->ts
.u
.cl
->length
)
5967 tmp
= fold_convert (gfc_charlen_type_node
,
5968 gfc_get_cfi_desc_elem_len (cfi
));
5969 if (e
->ts
.kind
!= 1)
5970 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
5971 gfc_charlen_type_node
, tmp
,
5972 build_int_cst (gfc_charlen_type_node
,
5974 gfc_add_modify (&block2
, gfc_strlen
, tmp
);
5977 tmp
= gfc_get_cfi_desc_base_addr (cfi
),
5978 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
5979 tmp
, null_pointer_node
);
5980 tmp
= build3_v (COND_EXPR
, tmp
, gfc_finish_block (&block2
),
5981 build_empty_stmt (input_location
));
5982 gfc_add_expr_to_block (&block
, tmp
);
5985 gfc_add_block_to_block (&block
, &se
.post
);
5986 if (present
&& block
.head
)
5988 tmp
= build3_v (COND_EXPR
, present
, gfc_finish_block (&block
),
5989 build_empty_stmt (input_location
));
5990 gfc_add_expr_to_block (&parmse
->post
, tmp
);
5992 else if (block
.head
)
5993 gfc_add_block_to_block (&parmse
->post
, &block
);
5997 /* Generate code for a procedure call. Note can return se->post != NULL.
5998 If se->direct_byref is set then se->expr contains the return parameter.
5999 Return nonzero, if the call has alternate specifiers.
6000 'expr' is only needed for procedure pointer components. */
6003 gfc_conv_procedure_call (gfc_se
* se
, gfc_symbol
* sym
,
6004 gfc_actual_arglist
* args
, gfc_expr
* expr
,
6005 vec
<tree
, va_gc
> *append_args
)
6007 gfc_interface_mapping mapping
;
6008 vec
<tree
, va_gc
> *arglist
;
6009 vec
<tree
, va_gc
> *retargs
;
6013 gfc_array_info
*info
;
6020 vec
<tree
, va_gc
> *stringargs
;
6021 vec
<tree
, va_gc
> *optionalargs
;
6023 gfc_formal_arglist
*formal
;
6024 gfc_actual_arglist
*arg
;
6025 int has_alternate_specifier
= 0;
6026 bool need_interface_mapping
;
6033 enum {MISSING
= 0, ELEMENTAL
, SCALAR
, SCALAR_POINTER
, ARRAY
};
6034 gfc_component
*comp
= NULL
;
6041 optionalargs
= NULL
;
6046 comp
= gfc_get_proc_ptr_comp (expr
);
6048 bool elemental_proc
= (comp
6049 && comp
->ts
.interface
6050 && comp
->ts
.interface
->attr
.elemental
)
6051 || (comp
&& comp
->attr
.elemental
)
6052 || sym
->attr
.elemental
;
6056 if (!elemental_proc
)
6058 gcc_assert (se
->ss
->info
->type
== GFC_SS_FUNCTION
);
6059 if (se
->ss
->info
->useflags
)
6061 gcc_assert ((!comp
&& gfc_return_by_reference (sym
)
6062 && sym
->result
->attr
.dimension
)
6063 || (comp
&& comp
->attr
.dimension
)
6064 || gfc_is_class_array_function (expr
));
6065 gcc_assert (se
->loop
!= NULL
);
6066 /* Access the previously obtained result. */
6067 gfc_conv_tmp_array_ref (se
);
6071 info
= &se
->ss
->info
->data
.array
;
6076 stmtblock_t post
, clobbers
;
6077 gfc_init_block (&post
);
6078 gfc_init_block (&clobbers
);
6079 gfc_init_interface_mapping (&mapping
);
6082 formal
= gfc_sym_get_dummy_args (sym
);
6083 need_interface_mapping
= sym
->attr
.dimension
||
6084 (sym
->ts
.type
== BT_CHARACTER
6085 && sym
->ts
.u
.cl
->length
6086 && sym
->ts
.u
.cl
->length
->expr_type
6091 formal
= comp
->ts
.interface
? comp
->ts
.interface
->formal
: NULL
;
6092 need_interface_mapping
= comp
->attr
.dimension
||
6093 (comp
->ts
.type
== BT_CHARACTER
6094 && comp
->ts
.u
.cl
->length
6095 && comp
->ts
.u
.cl
->length
->expr_type
6099 base_object
= NULL_TREE
;
6100 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
6101 is the third and fourth argument to such a function call a value
6102 denoting the number of elements to copy (i.e., most of the time the
6103 length of a deferred length string). */
6104 ulim_copy
= (formal
== NULL
)
6105 && UNLIMITED_POLY (sym
)
6106 && comp
&& (strcmp ("_copy", comp
->name
) == 0);
6108 /* Evaluate the arguments. */
6109 for (arg
= args
, argc
= 0; arg
!= NULL
;
6110 arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
, ++argc
)
6112 bool finalized
= false;
6113 tree derived_array
= NULL_TREE
;
6116 fsym
= formal
? formal
->sym
: NULL
;
6117 parm_kind
= MISSING
;
6119 /* If the procedure requires an explicit interface, the actual
6120 argument is passed according to the corresponding formal
6121 argument. If the corresponding formal argument is a POINTER,
6122 ALLOCATABLE or assumed shape, we do not use g77's calling
6123 convention, and pass the address of the array descriptor
6124 instead. Otherwise we use g77's calling convention, in other words
6125 pass the array data pointer without descriptor. */
6126 bool nodesc_arg
= fsym
!= NULL
6127 && !(fsym
->attr
.pointer
|| fsym
->attr
.allocatable
)
6129 && fsym
->as
->type
!= AS_ASSUMED_SHAPE
6130 && fsym
->as
->type
!= AS_ASSUMED_RANK
;
6132 nodesc_arg
= nodesc_arg
|| !comp
->attr
.always_explicit
;
6134 nodesc_arg
= nodesc_arg
|| !sym
->attr
.always_explicit
;
6136 /* Class array expressions are sometimes coming completely unadorned
6137 with either arrayspec or _data component. Correct that here.
6138 OOP-TODO: Move this to the frontend. */
6139 if (e
&& e
->expr_type
== EXPR_VARIABLE
6141 && e
->ts
.type
== BT_CLASS
6142 && (CLASS_DATA (e
)->attr
.codimension
6143 || CLASS_DATA (e
)->attr
.dimension
))
6145 gfc_typespec temp_ts
= e
->ts
;
6146 gfc_add_class_array_ref (e
);
6152 if (se
->ignore_optional
)
6154 /* Some intrinsics have already been resolved to the correct
6158 else if (arg
->label
)
6160 has_alternate_specifier
= 1;
6165 gfc_init_se (&parmse
, NULL
);
6167 /* For scalar arguments with VALUE attribute which are passed by
6168 value, pass "0" and a hidden argument gives the optional
6170 if (fsym
&& fsym
->attr
.optional
&& fsym
->attr
.value
6171 && !fsym
->attr
.dimension
&& fsym
->ts
.type
!= BT_CLASS
6172 && !gfc_bt_struct (sym
->ts
.type
))
6174 if (fsym
->ts
.type
== BT_CHARACTER
)
6176 /* Pass a NULL pointer for an absent CHARACTER arg
6177 and a length of zero. */
6178 parmse
.expr
= null_pointer_node
;
6179 parmse
.string_length
6180 = build_int_cst (gfc_charlen_type_node
,
6184 parmse
.expr
= fold_convert (gfc_sym_type (fsym
),
6186 vec_safe_push (optionalargs
, boolean_false_node
);
6190 /* Pass a NULL pointer for an absent arg. */
6191 parmse
.expr
= null_pointer_node
;
6192 gfc_dummy_arg
* const dummy_arg
= arg
->associated_dummy
;
6194 && gfc_dummy_arg_get_typespec (*dummy_arg
).type
6196 parmse
.string_length
= build_int_cst (gfc_charlen_type_node
,
6201 else if (arg
->expr
->expr_type
== EXPR_NULL
6202 && fsym
&& !fsym
->attr
.pointer
6203 && (fsym
->ts
.type
!= BT_CLASS
6204 || !CLASS_DATA (fsym
)->attr
.class_pointer
))
6206 /* Pass a NULL pointer to denote an absent arg. */
6207 gcc_assert (fsym
->attr
.optional
&& !fsym
->attr
.allocatable
6208 && (fsym
->ts
.type
!= BT_CLASS
6209 || !CLASS_DATA (fsym
)->attr
.allocatable
));
6210 gfc_init_se (&parmse
, NULL
);
6211 parmse
.expr
= null_pointer_node
;
6212 if (arg
->associated_dummy
6213 && gfc_dummy_arg_get_typespec (*arg
->associated_dummy
).type
6215 parmse
.string_length
= build_int_cst (gfc_charlen_type_node
, 0);
6217 else if (fsym
&& fsym
->ts
.type
== BT_CLASS
6218 && e
->ts
.type
== BT_DERIVED
)
6220 /* The derived type needs to be converted to a temporary
6222 gfc_init_se (&parmse
, se
);
6223 gfc_conv_derived_to_class (&parmse
, e
, fsym
->ts
, NULL
,
6225 && e
->expr_type
== EXPR_VARIABLE
6226 && e
->symtree
->n
.sym
->attr
.optional
,
6227 CLASS_DATA (fsym
)->attr
.class_pointer
6228 || CLASS_DATA (fsym
)->attr
.allocatable
,
6231 else if (UNLIMITED_POLY (fsym
) && e
->ts
.type
!= BT_CLASS
6232 && e
->ts
.type
!= BT_PROCEDURE
6233 && (gfc_expr_attr (e
).flavor
!= FL_PROCEDURE
6234 || gfc_expr_attr (e
).proc
!= PROC_UNKNOWN
))
6236 /* The intrinsic type needs to be converted to a temporary
6237 CLASS object for the unlimited polymorphic formal. */
6238 gfc_find_vtab (&e
->ts
);
6239 gfc_init_se (&parmse
, se
);
6240 gfc_conv_intrinsic_to_class (&parmse
, e
, fsym
->ts
);
6243 else if (se
->ss
&& se
->ss
->info
->useflags
)
6249 /* An elemental function inside a scalarized loop. */
6250 gfc_init_se (&parmse
, se
);
6251 parm_kind
= ELEMENTAL
;
6253 /* When no fsym is present, ulim_copy is set and this is a third or
6254 fourth argument, use call-by-value instead of by reference to
6255 hand the length properties to the copy routine (i.e., most of the
6256 time this will be a call to a __copy_character_* routine where the
6257 third and fourth arguments are the lengths of a deferred length
6259 if ((fsym
&& fsym
->attr
.value
)
6260 || (ulim_copy
&& (argc
== 2 || argc
== 3)))
6261 gfc_conv_expr (&parmse
, e
);
6263 gfc_conv_expr_reference (&parmse
, e
);
6265 if (e
->ts
.type
== BT_CHARACTER
&& !e
->rank
6266 && e
->expr_type
== EXPR_FUNCTION
)
6267 parmse
.expr
= build_fold_indirect_ref_loc (input_location
,
6270 if (fsym
&& fsym
->ts
.type
== BT_DERIVED
6271 && gfc_is_class_container_ref (e
))
6273 parmse
.expr
= gfc_class_data_get (parmse
.expr
);
6275 if (fsym
->attr
.optional
&& e
->expr_type
== EXPR_VARIABLE
6276 && e
->symtree
->n
.sym
->attr
.optional
)
6278 tree cond
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
6279 parmse
.expr
= build3_loc (input_location
, COND_EXPR
,
6280 TREE_TYPE (parmse
.expr
),
6282 fold_convert (TREE_TYPE (parmse
.expr
),
6283 null_pointer_node
));
6287 /* If we are passing an absent array as optional dummy to an
6288 elemental procedure, make sure that we pass NULL when the data
6289 pointer is NULL. We need this extra conditional because of
6290 scalarization which passes arrays elements to the procedure,
6291 ignoring the fact that the array can be absent/unallocated/... */
6292 if (ss
->info
->can_be_null_ref
&& ss
->info
->type
!= GFC_SS_REFERENCE
)
6294 tree descriptor_data
;
6296 descriptor_data
= ss
->info
->data
.array
.data
;
6297 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
6299 fold_convert (TREE_TYPE (descriptor_data
),
6300 null_pointer_node
));
6302 = fold_build3_loc (input_location
, COND_EXPR
,
6303 TREE_TYPE (parmse
.expr
),
6304 gfc_unlikely (tmp
, PRED_FORTRAN_ABSENT_DUMMY
),
6305 fold_convert (TREE_TYPE (parmse
.expr
),
6310 /* The scalarizer does not repackage the reference to a class
6311 array - instead it returns a pointer to the data element. */
6312 if (fsym
&& fsym
->ts
.type
== BT_CLASS
&& e
->ts
.type
== BT_CLASS
)
6313 gfc_conv_class_to_class (&parmse
, e
, fsym
->ts
, true,
6314 fsym
->attr
.intent
!= INTENT_IN
6315 && (CLASS_DATA (fsym
)->attr
.class_pointer
6316 || CLASS_DATA (fsym
)->attr
.allocatable
),
6318 && e
->expr_type
== EXPR_VARIABLE
6319 && e
->symtree
->n
.sym
->attr
.optional
,
6320 CLASS_DATA (fsym
)->attr
.class_pointer
6321 || CLASS_DATA (fsym
)->attr
.allocatable
);
6328 gfc_init_se (&parmse
, NULL
);
6330 /* Check whether the expression is a scalar or not; we cannot use
6331 e->rank as it can be nonzero for functions arguments. */
6332 argss
= gfc_walk_expr (e
);
6333 scalar
= argss
== gfc_ss_terminator
;
6335 gfc_free_ss_chain (argss
);
6337 /* Special handling for passing scalar polymorphic coarrays;
6338 otherwise one passes "class->_data.data" instead of "&class". */
6339 if (e
->rank
== 0 && e
->ts
.type
== BT_CLASS
6340 && fsym
&& fsym
->ts
.type
== BT_CLASS
6341 && CLASS_DATA (fsym
)->attr
.codimension
6342 && !CLASS_DATA (fsym
)->attr
.dimension
)
6344 gfc_add_class_array_ref (e
);
6345 parmse
.want_coarray
= 1;
6349 /* A scalar or transformational function. */
6352 if (e
->expr_type
== EXPR_VARIABLE
6353 && e
->symtree
->n
.sym
->attr
.cray_pointee
6354 && fsym
&& fsym
->attr
.flavor
== FL_PROCEDURE
)
6356 /* The Cray pointer needs to be converted to a pointer to
6357 a type given by the expression. */
6358 gfc_conv_expr (&parmse
, e
);
6359 type
= build_pointer_type (TREE_TYPE (parmse
.expr
));
6360 tmp
= gfc_get_symbol_decl (e
->symtree
->n
.sym
->cp_pointer
);
6361 parmse
.expr
= convert (type
, tmp
);
6364 else if (sym
->attr
.is_bind_c
&& e
&& is_CFI_desc (fsym
, NULL
))
6365 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6366 gfc_conv_gfc_desc_to_cfi_desc (&parmse
, e
, fsym
);
6368 else if (fsym
&& fsym
->attr
.value
)
6370 if (fsym
->ts
.type
== BT_CHARACTER
6371 && fsym
->ts
.is_c_interop
6372 && fsym
->ns
->proc_name
!= NULL
6373 && fsym
->ns
->proc_name
->attr
.is_bind_c
)
6376 conv_scalar_char_value (fsym
, &parmse
, &e
);
6377 if (parmse
.expr
== NULL
)
6378 gfc_conv_expr (&parmse
, e
);
6382 gfc_conv_expr (&parmse
, e
);
6383 if (fsym
->attr
.optional
6384 && fsym
->ts
.type
!= BT_CLASS
6385 && fsym
->ts
.type
!= BT_DERIVED
)
6387 if (e
->expr_type
!= EXPR_VARIABLE
6388 || !e
->symtree
->n
.sym
->attr
.optional
6390 vec_safe_push (optionalargs
, boolean_true_node
);
6393 tmp
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
6394 if (!e
->symtree
->n
.sym
->attr
.value
)
6396 = fold_build3_loc (input_location
, COND_EXPR
,
6397 TREE_TYPE (parmse
.expr
),
6399 fold_convert (TREE_TYPE (parmse
.expr
),
6400 integer_zero_node
));
6402 vec_safe_push (optionalargs
,
6403 fold_convert (boolean_type_node
,
6410 else if (arg
->name
&& arg
->name
[0] == '%')
6411 /* Argument list functions %VAL, %LOC and %REF are signalled
6412 through arg->name. */
6413 conv_arglist_function (&parmse
, arg
->expr
, arg
->name
);
6414 else if ((e
->expr_type
== EXPR_FUNCTION
)
6415 && ((e
->value
.function
.esym
6416 && e
->value
.function
.esym
->result
->attr
.pointer
)
6417 || (!e
->value
.function
.esym
6418 && e
->symtree
->n
.sym
->attr
.pointer
))
6419 && fsym
&& fsym
->attr
.target
)
6420 /* Make sure the function only gets called once. */
6421 gfc_conv_expr_reference (&parmse
, e
);
6422 else if (e
->expr_type
== EXPR_FUNCTION
6423 && e
->symtree
->n
.sym
->result
6424 && e
->symtree
->n
.sym
->result
!= e
->symtree
->n
.sym
6425 && e
->symtree
->n
.sym
->result
->attr
.proc_pointer
)
6427 /* Functions returning procedure pointers. */
6428 gfc_conv_expr (&parmse
, e
);
6429 if (fsym
&& fsym
->attr
.proc_pointer
)
6430 parmse
.expr
= gfc_build_addr_expr (NULL_TREE
, parmse
.expr
);
6435 if (e
->ts
.type
== BT_CLASS
&& fsym
6436 && fsym
->ts
.type
== BT_CLASS
6437 && (!CLASS_DATA (fsym
)->as
6438 || CLASS_DATA (fsym
)->as
->type
!= AS_ASSUMED_RANK
)
6439 && CLASS_DATA (e
)->attr
.codimension
)
6441 gcc_assert (!CLASS_DATA (fsym
)->attr
.codimension
);
6442 gcc_assert (!CLASS_DATA (fsym
)->as
);
6443 gfc_add_class_array_ref (e
);
6444 parmse
.want_coarray
= 1;
6445 gfc_conv_expr_reference (&parmse
, e
);
6446 class_scalar_coarray_to_class (&parmse
, e
, fsym
->ts
,
6448 && e
->expr_type
== EXPR_VARIABLE
);
6450 else if (e
->ts
.type
== BT_CLASS
&& fsym
6451 && fsym
->ts
.type
== BT_CLASS
6452 && !CLASS_DATA (fsym
)->as
6453 && !CLASS_DATA (e
)->as
6454 && strcmp (fsym
->ts
.u
.derived
->name
,
6455 e
->ts
.u
.derived
->name
))
6457 type
= gfc_typenode_for_spec (&fsym
->ts
);
6458 var
= gfc_create_var (type
, fsym
->name
);
6459 gfc_conv_expr (&parmse
, e
);
6460 if (fsym
->attr
.optional
6461 && e
->expr_type
== EXPR_VARIABLE
6462 && e
->symtree
->n
.sym
->attr
.optional
)
6466 tmp
= gfc_build_addr_expr (NULL_TREE
, parmse
.expr
);
6467 cond
= fold_build2_loc (input_location
, NE_EXPR
,
6468 logical_type_node
, tmp
,
6469 fold_convert (TREE_TYPE (tmp
),
6470 null_pointer_node
));
6471 gfc_start_block (&block
);
6472 gfc_add_modify (&block
, var
,
6473 fold_build1_loc (input_location
,
6475 type
, parmse
.expr
));
6476 gfc_add_expr_to_block (&parmse
.pre
,
6477 fold_build3_loc (input_location
,
6478 COND_EXPR
, void_type_node
,
6479 cond
, gfc_finish_block (&block
),
6480 build_empty_stmt (input_location
)));
6481 parmse
.expr
= gfc_build_addr_expr (NULL_TREE
, var
);
6482 parmse
.expr
= build3_loc (input_location
, COND_EXPR
,
6483 TREE_TYPE (parmse
.expr
),
6485 fold_convert (TREE_TYPE (parmse
.expr
),
6486 null_pointer_node
));
6490 /* Since the internal representation of unlimited
6491 polymorphic expressions includes an extra field
6492 that other class objects do not, a cast to the
6493 formal type does not work. */
6494 if (!UNLIMITED_POLY (e
) && UNLIMITED_POLY (fsym
))
6498 /* Set the _data field. */
6499 tmp
= gfc_class_data_get (var
);
6500 efield
= fold_convert (TREE_TYPE (tmp
),
6501 gfc_class_data_get (parmse
.expr
));
6502 gfc_add_modify (&parmse
.pre
, tmp
, efield
);
6504 /* Set the _vptr field. */
6505 tmp
= gfc_class_vptr_get (var
);
6506 efield
= fold_convert (TREE_TYPE (tmp
),
6507 gfc_class_vptr_get (parmse
.expr
));
6508 gfc_add_modify (&parmse
.pre
, tmp
, efield
);
6510 /* Set the _len field. */
6511 tmp
= gfc_class_len_get (var
);
6512 gfc_add_modify (&parmse
.pre
, tmp
,
6513 build_int_cst (TREE_TYPE (tmp
), 0));
6517 tmp
= fold_build1_loc (input_location
,
6520 gfc_add_modify (&parmse
.pre
, var
, tmp
);
6523 parmse
.expr
= gfc_build_addr_expr (NULL_TREE
, var
);
6528 gfc_conv_expr_reference (&parmse
, e
);
6530 gfc_symbol
*dsym
= fsym
;
6531 gfc_dummy_arg
*dummy
;
6533 /* Use associated dummy as fallback for formal
6534 argument if there is no explicit interface. */
6536 && (dummy
= arg
->associated_dummy
)
6537 && dummy
->intrinsicness
== GFC_NON_INTRINSIC_DUMMY_ARG
6538 && dummy
->u
.non_intrinsic
->sym
)
6539 dsym
= dummy
->u
.non_intrinsic
->sym
;
6542 && dsym
->attr
.intent
== INTENT_OUT
6543 && !dsym
->attr
.allocatable
6544 && !dsym
->attr
.pointer
6545 && e
->expr_type
== EXPR_VARIABLE
6548 && e
->symtree
->n
.sym
6549 && !e
->symtree
->n
.sym
->attr
.dimension
6550 && e
->ts
.type
!= BT_CHARACTER
6551 && e
->ts
.type
!= BT_CLASS
6552 && (e
->ts
.type
!= BT_DERIVED
6553 || (dsym
->ts
.type
== BT_DERIVED
6554 && e
->ts
.u
.derived
== dsym
->ts
.u
.derived
6555 /* Types with allocatable components are
6556 excluded from clobbering because we need
6557 the unclobbered pointers to free the
6558 allocatable components in the callee.
6559 Same goes for finalizable types or types
6560 with finalizable components, we need to
6561 pass the unclobbered values to the
6562 finalization routines.
6563 For parameterized types, it's less clear
6564 but they may not have a constant size
6565 so better exclude them in any case. */
6566 && !e
->ts
.u
.derived
->attr
.alloc_comp
6567 && !e
->ts
.u
.derived
->attr
.pdt_type
6568 && !gfc_is_finalizable (e
->ts
.u
.derived
, NULL
)))
6569 && !sym
->attr
.elemental
)
6572 var
= build_fold_indirect_ref_loc (input_location
,
6574 tree clobber
= build_clobber (TREE_TYPE (var
));
6575 gfc_add_modify (&clobbers
, var
, clobber
);
6578 /* Catch base objects that are not variables. */
6579 if (e
->ts
.type
== BT_CLASS
6580 && e
->expr_type
!= EXPR_VARIABLE
6581 && expr
&& e
== expr
->base_expr
)
6582 base_object
= build_fold_indirect_ref_loc (input_location
,
6585 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6586 allocated on entry, it must be deallocated. */
6587 if (fsym
&& fsym
->attr
.intent
== INTENT_OUT
6588 && (fsym
->attr
.allocatable
6589 || (fsym
->ts
.type
== BT_CLASS
6590 && CLASS_DATA (fsym
)->attr
.allocatable
))
6591 && !is_CFI_desc (fsym
, NULL
))
6596 gfc_init_block (&block
);
6598 if (e
->ts
.type
== BT_CLASS
)
6599 ptr
= gfc_class_data_get (ptr
);
6601 tmp
= gfc_deallocate_scalar_with_status (ptr
, NULL_TREE
,
6604 gfc_add_expr_to_block (&block
, tmp
);
6605 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
6606 void_type_node
, ptr
,
6608 gfc_add_expr_to_block (&block
, tmp
);
6610 if (fsym
->ts
.type
== BT_CLASS
&& UNLIMITED_POLY (fsym
))
6612 gfc_add_modify (&block
, ptr
,
6613 fold_convert (TREE_TYPE (ptr
),
6614 null_pointer_node
));
6615 gfc_add_expr_to_block (&block
, tmp
);
6617 else if (fsym
->ts
.type
== BT_CLASS
)
6620 vtab
= gfc_find_derived_vtab (fsym
->ts
.u
.derived
);
6621 tmp
= gfc_get_symbol_decl (vtab
);
6622 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
6623 ptr
= gfc_class_vptr_get (parmse
.expr
);
6624 gfc_add_modify (&block
, ptr
,
6625 fold_convert (TREE_TYPE (ptr
), tmp
));
6626 gfc_add_expr_to_block (&block
, tmp
);
6629 if (fsym
->attr
.optional
6630 && e
->expr_type
== EXPR_VARIABLE
6631 && e
->symtree
->n
.sym
->attr
.optional
)
6633 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
6635 gfc_conv_expr_present (e
->symtree
->n
.sym
),
6636 gfc_finish_block (&block
),
6637 build_empty_stmt (input_location
));
6640 tmp
= gfc_finish_block (&block
);
6642 gfc_add_expr_to_block (&se
->pre
, tmp
);
6645 /* A class array element needs converting back to be a
6646 class object, if the formal argument is a class object. */
6647 if (fsym
&& fsym
->ts
.type
== BT_CLASS
6648 && e
->ts
.type
== BT_CLASS
6649 && ((CLASS_DATA (fsym
)->as
6650 && CLASS_DATA (fsym
)->as
->type
== AS_ASSUMED_RANK
)
6651 || CLASS_DATA (e
)->attr
.dimension
))
6652 gfc_conv_class_to_class (&parmse
, e
, fsym
->ts
, false,
6653 fsym
->attr
.intent
!= INTENT_IN
6654 && (CLASS_DATA (fsym
)->attr
.class_pointer
6655 || CLASS_DATA (fsym
)->attr
.allocatable
),
6657 && e
->expr_type
== EXPR_VARIABLE
6658 && e
->symtree
->n
.sym
->attr
.optional
,
6659 CLASS_DATA (fsym
)->attr
.class_pointer
6660 || CLASS_DATA (fsym
)->attr
.allocatable
);
6662 if (fsym
&& (fsym
->ts
.type
== BT_DERIVED
6663 || fsym
->ts
.type
== BT_ASSUMED
)
6664 && e
->ts
.type
== BT_CLASS
6665 && !CLASS_DATA (e
)->attr
.dimension
6666 && !CLASS_DATA (e
)->attr
.codimension
)
6668 parmse
.expr
= gfc_class_data_get (parmse
.expr
);
6669 /* The result is a class temporary, whose _data component
6670 must be freed to avoid a memory leak. */
6671 if (e
->expr_type
== EXPR_FUNCTION
6672 && CLASS_DATA (e
)->attr
.allocatable
)
6678 /* Borrow the function symbol to make a call to
6679 gfc_add_finalizer_call and then restore it. */
6680 tmp
= e
->symtree
->n
.sym
->backend_decl
;
6681 e
->symtree
->n
.sym
->backend_decl
6682 = TREE_OPERAND (parmse
.expr
, 0);
6683 e
->symtree
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
6684 var
= gfc_lval_expr_from_sym (e
->symtree
->n
.sym
);
6685 finalized
= gfc_add_finalizer_call (&parmse
.post
,
6687 gfc_free_expr (var
);
6688 e
->symtree
->n
.sym
->backend_decl
= tmp
;
6689 e
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
6691 /* Then free the class _data. */
6692 zero
= build_int_cst (TREE_TYPE (parmse
.expr
), 0);
6693 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
6696 tmp
= build3_v (COND_EXPR
, tmp
,
6697 gfc_call_free (parmse
.expr
),
6698 build_empty_stmt (input_location
));
6699 gfc_add_expr_to_block (&parmse
.post
, tmp
);
6700 gfc_add_modify (&parmse
.post
, parmse
.expr
, zero
);
6704 /* Wrap scalar variable in a descriptor. We need to convert
6705 the address of a pointer back to the pointer itself before,
6706 we can assign it to the data field. */
6708 if (fsym
&& fsym
->as
&& fsym
->as
->type
== AS_ASSUMED_RANK
6709 && fsym
->ts
.type
!= BT_CLASS
&& e
->expr_type
!= EXPR_NULL
)
6712 if (TREE_CODE (tmp
) == ADDR_EXPR
)
6713 tmp
= TREE_OPERAND (tmp
, 0);
6714 parmse
.expr
= gfc_conv_scalar_to_descriptor (&parmse
, tmp
,
6716 parmse
.expr
= gfc_build_addr_expr (NULL_TREE
,
6719 else if (fsym
&& e
->expr_type
!= EXPR_NULL
6720 && ((fsym
->attr
.pointer
6721 && fsym
->attr
.flavor
!= FL_PROCEDURE
)
6722 || (fsym
->attr
.proc_pointer
6723 && !(e
->expr_type
== EXPR_VARIABLE
6724 && e
->symtree
->n
.sym
->attr
.dummy
))
6725 || (fsym
->attr
.proc_pointer
6726 && e
->expr_type
== EXPR_VARIABLE
6727 && gfc_is_proc_ptr_comp (e
))
6728 || (fsym
->attr
.allocatable
6729 && fsym
->attr
.flavor
!= FL_PROCEDURE
)))
6731 /* Scalar pointer dummy args require an extra level of
6732 indirection. The null pointer already contains
6733 this level of indirection. */
6734 parm_kind
= SCALAR_POINTER
;
6735 parmse
.expr
= gfc_build_addr_expr (NULL_TREE
, parmse
.expr
);
6739 else if (e
->ts
.type
== BT_CLASS
6740 && fsym
&& fsym
->ts
.type
== BT_CLASS
6741 && (CLASS_DATA (fsym
)->attr
.dimension
6742 || CLASS_DATA (fsym
)->attr
.codimension
))
6744 /* Pass a class array. */
6745 parmse
.use_offset
= 1;
6746 gfc_conv_expr_descriptor (&parmse
, e
);
6748 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6749 allocated on entry, it must be deallocated. */
6750 if (fsym
->attr
.intent
== INTENT_OUT
6751 && CLASS_DATA (fsym
)->attr
.allocatable
)
6756 gfc_init_block (&block
);
6758 ptr
= gfc_class_data_get (ptr
);
6760 tmp
= gfc_deallocate_with_status (ptr
, NULL_TREE
,
6761 NULL_TREE
, NULL_TREE
,
6763 GFC_CAF_COARRAY_NOCOARRAY
);
6764 gfc_add_expr_to_block (&block
, tmp
);
6765 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
,
6766 void_type_node
, ptr
,
6768 gfc_add_expr_to_block (&block
, tmp
);
6769 gfc_reset_vptr (&block
, e
);
6771 if (fsym
->attr
.optional
6772 && e
->expr_type
== EXPR_VARIABLE
6774 || (e
->ref
->type
== REF_ARRAY
6775 && e
->ref
->u
.ar
.type
!= AR_FULL
))
6776 && e
->symtree
->n
.sym
->attr
.optional
)
6778 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
6780 gfc_conv_expr_present (e
->symtree
->n
.sym
),
6781 gfc_finish_block (&block
),
6782 build_empty_stmt (input_location
));
6785 tmp
= gfc_finish_block (&block
);
6787 gfc_add_expr_to_block (&se
->pre
, tmp
);
6790 /* The conversion does not repackage the reference to a class
6791 array - _data descriptor. */
6792 gfc_conv_class_to_class (&parmse
, e
, fsym
->ts
, false,
6793 fsym
->attr
.intent
!= INTENT_IN
6794 && (CLASS_DATA (fsym
)->attr
.class_pointer
6795 || CLASS_DATA (fsym
)->attr
.allocatable
),
6797 && e
->expr_type
== EXPR_VARIABLE
6798 && e
->symtree
->n
.sym
->attr
.optional
,
6799 CLASS_DATA (fsym
)->attr
.class_pointer
6800 || CLASS_DATA (fsym
)->attr
.allocatable
);
6804 /* If the argument is a function call that may not create
6805 a temporary for the result, we have to check that we
6806 can do it, i.e. that there is no alias between this
6807 argument and another one. */
6808 if (gfc_get_noncopying_intrinsic_argument (e
) != NULL
)
6814 intent
= fsym
->attr
.intent
;
6816 intent
= INTENT_UNKNOWN
;
6818 if (gfc_check_fncall_dependency (e
, intent
, sym
, args
,
6820 parmse
.force_tmp
= 1;
6822 iarg
= e
->value
.function
.actual
->expr
;
6824 /* Temporary needed if aliasing due to host association. */
6825 if (sym
->attr
.contained
6827 && !sym
->attr
.implicit_pure
6828 && !sym
->attr
.use_assoc
6829 && iarg
->expr_type
== EXPR_VARIABLE
6830 && sym
->ns
== iarg
->symtree
->n
.sym
->ns
)
6831 parmse
.force_tmp
= 1;
6833 /* Ditto within module. */
6834 if (sym
->attr
.use_assoc
6836 && !sym
->attr
.implicit_pure
6837 && iarg
->expr_type
== EXPR_VARIABLE
6838 && sym
->module
== iarg
->symtree
->n
.sym
->module
)
6839 parmse
.force_tmp
= 1;
6842 /* Special case for assumed-rank arrays: when passing an
6843 argument to a nonallocatable/nonpointer dummy, the bounds have
6844 to be reset as otherwise a last-dim ubound of -1 is
6845 indistinguishable from an assumed-size array in the callee. */
6846 if (!sym
->attr
.is_bind_c
&& e
&& fsym
&& fsym
->as
6847 && fsym
->as
->type
== AS_ASSUMED_RANK
6849 && e
->expr_type
== EXPR_VARIABLE
6850 && ((fsym
->ts
.type
== BT_CLASS
6851 && !CLASS_DATA (fsym
)->attr
.class_pointer
6852 && !CLASS_DATA (fsym
)->attr
.allocatable
)
6853 || (fsym
->ts
.type
!= BT_CLASS
6854 && !fsym
->attr
.pointer
&& !fsym
->attr
.allocatable
)))
6856 /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
6858 for (ref
= e
->ref
; ref
->next
; ref
= ref
->next
)
6860 if (ref
->u
.ar
.type
== AR_FULL
6861 && ref
->u
.ar
.as
->type
!= AS_ASSUMED_SIZE
)
6862 ref
->u
.ar
.type
= AR_SECTION
;
6865 if (sym
->attr
.is_bind_c
&& e
&& is_CFI_desc (fsym
, NULL
))
6866 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6867 gfc_conv_gfc_desc_to_cfi_desc (&parmse
, e
, fsym
);
6869 else if (e
->expr_type
== EXPR_VARIABLE
6870 && is_subref_array (e
)
6871 && !(fsym
&& fsym
->attr
.pointer
))
6872 /* The actual argument is a component reference to an
6873 array of derived types. In this case, the argument
6874 is converted to a temporary, which is passed and then
6875 written back after the procedure call. */
6876 gfc_conv_subref_array_arg (&parmse
, e
, nodesc_arg
,
6877 fsym
? fsym
->attr
.intent
: INTENT_INOUT
,
6878 fsym
&& fsym
->attr
.pointer
);
6880 else if (e
->ts
.type
== BT_CLASS
&& CLASS_DATA (e
)->as
6881 && CLASS_DATA (e
)->as
->type
== AS_ASSUMED_SIZE
6882 && nodesc_arg
&& fsym
->ts
.type
== BT_DERIVED
)
6883 /* An assumed size class actual argument being passed to
6884 a 'no descriptor' formal argument just requires the
6885 data pointer to be passed. For class dummy arguments
6886 this is stored in the symbol backend decl.. */
6887 parmse
.expr
= e
->symtree
->n
.sym
->backend_decl
;
6889 else if (gfc_is_class_array_ref (e
, NULL
)
6890 && fsym
&& fsym
->ts
.type
== BT_DERIVED
)
6891 /* The actual argument is a component reference to an
6892 array of derived types. In this case, the argument
6893 is converted to a temporary, which is passed and then
6894 written back after the procedure call.
6895 OOP-TODO: Insert code so that if the dynamic type is
6896 the same as the declared type, copy-in/copy-out does
6898 gfc_conv_subref_array_arg (&parmse
, e
, nodesc_arg
,
6900 fsym
->attr
.pointer
);
6902 else if (gfc_is_class_array_function (e
)
6903 && fsym
&& fsym
->ts
.type
== BT_DERIVED
)
6904 /* See previous comment. For function actual argument,
6905 the write out is not needed so the intent is set as
6908 e
->must_finalize
= 1;
6909 gfc_conv_subref_array_arg (&parmse
, e
, nodesc_arg
,
6910 INTENT_IN
, fsym
->attr
.pointer
);
6912 else if (fsym
&& fsym
->attr
.contiguous
6913 && !gfc_is_simply_contiguous (e
, false, true)
6914 && gfc_expr_is_variable (e
))
6916 gfc_conv_subref_array_arg (&parmse
, e
, nodesc_arg
,
6918 fsym
->attr
.pointer
);
6921 /* This is where we introduce a temporary to store the
6922 result of a non-lvalue array expression. */
6923 gfc_conv_array_parameter (&parmse
, e
, nodesc_arg
, fsym
,
6926 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6927 allocated on entry, it must be deallocated.
6928 CFI descriptors are handled elsewhere. */
6929 if (fsym
&& fsym
->attr
.allocatable
6930 && fsym
->attr
.intent
== INTENT_OUT
6931 && !is_CFI_desc (fsym
, NULL
))
6933 if (fsym
->ts
.type
== BT_DERIVED
6934 && fsym
->ts
.u
.derived
->attr
.alloc_comp
)
6936 // deallocate the components first
6937 tmp
= gfc_deallocate_alloc_comp (fsym
->ts
.u
.derived
,
6938 parmse
.expr
, e
->rank
);
6939 /* But check whether dummy argument is optional. */
6940 if (tmp
!= NULL_TREE
6941 && fsym
->attr
.optional
6942 && e
->expr_type
== EXPR_VARIABLE
6943 && e
->symtree
->n
.sym
->attr
.optional
)
6946 present
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
6947 tmp
= build3_v (COND_EXPR
, present
, tmp
,
6948 build_empty_stmt (input_location
));
6950 if (tmp
!= NULL_TREE
)
6951 gfc_add_expr_to_block (&se
->pre
, tmp
);
6955 /* With bind(C), the actual argument is replaced by a bind-C
6956 descriptor; in this case, the data component arrives here,
6957 which shall not be dereferenced, but still freed and
6959 if (TREE_TYPE(tmp
) != pvoid_type_node
)
6960 tmp
= build_fold_indirect_ref_loc (input_location
,
6962 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp
)))
6963 tmp
= gfc_conv_descriptor_data_get (tmp
);
6964 tmp
= gfc_deallocate_with_status (tmp
, NULL_TREE
, NULL_TREE
,
6965 NULL_TREE
, NULL_TREE
, true,
6967 GFC_CAF_COARRAY_NOCOARRAY
);
6968 if (fsym
->attr
.optional
6969 && e
->expr_type
== EXPR_VARIABLE
6970 && e
->symtree
->n
.sym
->attr
.optional
)
6971 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
6973 gfc_conv_expr_present (e
->symtree
->n
.sym
),
6974 tmp
, build_empty_stmt (input_location
));
6975 gfc_add_expr_to_block (&se
->pre
, tmp
);
6979 /* Special case for an assumed-rank dummy argument. */
6980 if (!sym
->attr
.is_bind_c
&& e
&& fsym
&& e
->rank
> 0
6981 && (fsym
->ts
.type
== BT_CLASS
6982 ? (CLASS_DATA (fsym
)->as
6983 && CLASS_DATA (fsym
)->as
->type
== AS_ASSUMED_RANK
)
6984 : (fsym
->as
&& fsym
->as
->type
== AS_ASSUMED_RANK
)))
6986 if (fsym
->ts
.type
== BT_CLASS
6987 ? (CLASS_DATA (fsym
)->attr
.class_pointer
6988 || CLASS_DATA (fsym
)->attr
.allocatable
)
6989 : (fsym
->attr
.pointer
|| fsym
->attr
.allocatable
))
6991 /* Unallocated allocatable arrays and unassociated pointer
6992 arrays need their dtype setting if they are argument
6993 associated with assumed rank dummies to set the rank. */
6994 set_dtype_for_unallocated (&parmse
, e
);
6996 else if (e
->expr_type
== EXPR_VARIABLE
6997 && e
->symtree
->n
.sym
->attr
.dummy
6998 && (e
->ts
.type
== BT_CLASS
6999 ? (e
->ref
&& e
->ref
->next
7000 && e
->ref
->next
->type
== REF_ARRAY
7001 && e
->ref
->next
->u
.ar
.type
== AR_FULL
7002 && e
->ref
->next
->u
.ar
.as
->type
== AS_ASSUMED_SIZE
)
7003 : (e
->ref
&& e
->ref
->type
== REF_ARRAY
7004 && e
->ref
->u
.ar
.type
== AR_FULL
7005 && e
->ref
->u
.ar
.as
->type
== AS_ASSUMED_SIZE
)))
7007 /* Assumed-size actual to assumed-rank dummy requires
7008 dim[rank-1].ubound = -1. */
7010 tmp
= build_fold_indirect_ref_loc (input_location
, parmse
.expr
);
7011 if (fsym
->ts
.type
== BT_CLASS
)
7012 tmp
= gfc_class_data_get (tmp
);
7013 minus_one
= build_int_cst (gfc_array_index_type
, -1);
7014 gfc_conv_descriptor_ubound_set (&parmse
.pre
, tmp
,
7015 gfc_rank_cst
[e
->rank
- 1],
7020 /* The case with fsym->attr.optional is that of a user subroutine
7021 with an interface indicating an optional argument. When we call
7022 an intrinsic subroutine, however, fsym is NULL, but we might still
7023 have an optional argument, so we proceed to the substitution
7025 if (e
&& (fsym
== NULL
|| fsym
->attr
.optional
))
7027 /* If an optional argument is itself an optional dummy argument,
7028 check its presence and substitute a null if absent. This is
7029 only needed when passing an array to an elemental procedure
7030 as then array elements are accessed - or no NULL pointer is
7031 allowed and a "1" or "0" should be passed if not present.
7032 When passing a non-array-descriptor full array to a
7033 non-array-descriptor dummy, no check is needed. For
7034 array-descriptor actual to array-descriptor dummy, see
7035 PR 41911 for why a check has to be inserted.
7036 fsym == NULL is checked as intrinsics required the descriptor
7037 but do not always set fsym.
7038 Also, it is necessary to pass a NULL pointer to library routines
7039 which usually ignore optional arguments, so they can handle
7040 these themselves. */
7041 if (e
->expr_type
== EXPR_VARIABLE
7042 && e
->symtree
->n
.sym
->attr
.optional
7043 && (((e
->rank
!= 0 && elemental_proc
)
7044 || e
->representation
.length
|| e
->ts
.type
== BT_CHARACTER
7048 && (fsym
->as
->type
== AS_ASSUMED_SHAPE
7049 || fsym
->as
->type
== AS_ASSUMED_RANK
7050 || fsym
->as
->type
== AS_DEFERRED
)))))
7051 || se
->ignore_optional
))
7052 gfc_conv_missing_dummy (&parmse
, e
, fsym
? fsym
->ts
: e
->ts
,
7053 e
->representation
.length
);
7058 /* Obtain the character length of an assumed character length
7059 length procedure from the typespec. */
7060 if (fsym
->ts
.type
== BT_CHARACTER
7061 && parmse
.string_length
== NULL_TREE
7062 && e
->ts
.type
== BT_PROCEDURE
7063 && e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
7064 && e
->symtree
->n
.sym
->ts
.u
.cl
->length
!= NULL
7065 && e
->symtree
->n
.sym
->ts
.u
.cl
->length
->expr_type
== EXPR_CONSTANT
)
7067 gfc_conv_const_charlen (e
->symtree
->n
.sym
->ts
.u
.cl
);
7068 parmse
.string_length
= e
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
;
7072 if (fsym
&& need_interface_mapping
&& e
)
7073 gfc_add_interface_mapping (&mapping
, fsym
, &parmse
, e
);
7075 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
7076 gfc_add_block_to_block (&post
, &parmse
.post
);
7078 /* Allocated allocatable components of derived types must be
7079 deallocated for non-variable scalars, array arguments to elemental
7080 procedures, and array arguments with descriptor to non-elemental
7081 procedures. As bounds information for descriptorless arrays is no
7082 longer available here, they are dealt with in trans-array.cc
7083 (gfc_conv_array_parameter). */
7084 if (e
&& (e
->ts
.type
== BT_DERIVED
|| e
->ts
.type
== BT_CLASS
)
7085 && e
->ts
.u
.derived
->attr
.alloc_comp
7086 && (e
->rank
== 0 || elemental_proc
|| !nodesc_arg
)
7087 && !expr_may_alias_variables (e
, elemental_proc
))
7090 /* It is known the e returns a structure type with at least one
7091 allocatable component. When e is a function, ensure that the
7092 function is called once only by using a temporary variable. */
7093 if (!DECL_P (parmse
.expr
))
7094 parmse
.expr
= gfc_evaluate_now_loc (input_location
,
7095 parmse
.expr
, &se
->pre
);
7097 if (fsym
&& fsym
->attr
.value
)
7100 tmp
= build_fold_indirect_ref_loc (input_location
,
7103 parm_rank
= e
->rank
;
7111 case (SCALAR_POINTER
):
7112 tmp
= build_fold_indirect_ref_loc (input_location
,
7117 if (e
->ts
.type
== BT_DERIVED
&& fsym
&& fsym
->ts
.type
== BT_CLASS
)
7119 /* The derived type is passed to gfc_deallocate_alloc_comp.
7120 Therefore, class actuals can be handled correctly but derived
7121 types passed to class formals need the _data component. */
7122 tmp
= gfc_class_data_get (tmp
);
7123 if (!CLASS_DATA (fsym
)->attr
.dimension
)
7124 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
7127 if (e
->expr_type
== EXPR_OP
7128 && e
->value
.op
.op
== INTRINSIC_PARENTHESES
7129 && e
->value
.op
.op1
->expr_type
== EXPR_VARIABLE
)
7132 local_tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
7133 local_tmp
= gfc_copy_alloc_comp (e
->ts
.u
.derived
, local_tmp
, tmp
,
7135 gfc_add_expr_to_block (&se
->post
, local_tmp
);
7138 if (!finalized
&& !e
->must_finalize
)
7140 bool scalar_res_outside_loop
;
7141 scalar_res_outside_loop
= e
->expr_type
== EXPR_FUNCTION
7145 /* Scalars passed to an assumed rank argument are converted to
7146 a descriptor. Obtain the data field before deallocating any
7147 allocatable components. */
7148 if (parm_rank
== 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp
)))
7149 tmp
= gfc_conv_descriptor_data_get (tmp
);
7151 if (scalar_res_outside_loop
)
7153 /* Go through the ss chain to find the argument and use
7154 the stored value. */
7155 gfc_ss
*tmp_ss
= parmse
.loop
->ss
;
7156 for (; tmp_ss
; tmp_ss
= tmp_ss
->next
)
7158 && tmp_ss
->info
->expr
== e
7159 && tmp_ss
->info
->data
.scalar
.value
!= NULL_TREE
)
7161 tmp
= tmp_ss
->info
->data
.scalar
.value
;
7168 if (derived_array
!= NULL_TREE
)
7169 tmp
= gfc_deallocate_alloc_comp (e
->ts
.u
.derived
,
7172 else if ((e
->ts
.type
== BT_CLASS
7173 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp
)))
7174 || e
->ts
.type
== BT_DERIVED
)
7175 tmp
= gfc_deallocate_alloc_comp (e
->ts
.u
.derived
, tmp
,
7177 else if (e
->ts
.type
== BT_CLASS
)
7178 tmp
= gfc_deallocate_alloc_comp (CLASS_DATA (e
)->ts
.u
.derived
,
7181 if (scalar_res_outside_loop
)
7182 gfc_add_expr_to_block (&parmse
.loop
->post
, tmp
);
7184 gfc_prepend_expr_to_block (&post
, tmp
);
7188 /* Add argument checking of passing an unallocated/NULL actual to
7189 a nonallocatable/nonpointer dummy. */
7191 if (gfc_option
.rtcheck
& GFC_RTCHECK_POINTER
&& e
!= NULL
)
7193 symbol_attribute attr
;
7197 symbol_attribute fsym_attr
;
7201 if (fsym
->ts
.type
== BT_CLASS
)
7203 fsym_attr
= CLASS_DATA (fsym
)->attr
;
7204 fsym_attr
.pointer
= fsym_attr
.class_pointer
;
7207 fsym_attr
= fsym
->attr
;
7210 if (e
->expr_type
== EXPR_VARIABLE
|| e
->expr_type
== EXPR_FUNCTION
)
7211 attr
= gfc_expr_attr (e
);
7213 goto end_pointer_check
;
7215 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
7216 allocatable to an optional dummy, cf. 12.5.2.12. */
7217 if (fsym
!= NULL
&& fsym
->attr
.optional
&& !attr
.proc_pointer
7218 && (gfc_option
.allow_std
& GFC_STD_F2008
) != 0)
7219 goto end_pointer_check
;
7223 /* If the actual argument is an optional pointer/allocatable and
7224 the formal argument takes an nonpointer optional value,
7225 it is invalid to pass a non-present argument on, even
7226 though there is no technical reason for this in gfortran.
7227 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
7228 tree present
, null_ptr
, type
;
7230 if (attr
.allocatable
7231 && (fsym
== NULL
|| !fsym_attr
.allocatable
))
7232 msg
= xasprintf ("Allocatable actual argument '%s' is not "
7233 "allocated or not present",
7234 e
->symtree
->n
.sym
->name
);
7235 else if (attr
.pointer
7236 && (fsym
== NULL
|| !fsym_attr
.pointer
))
7237 msg
= xasprintf ("Pointer actual argument '%s' is not "
7238 "associated or not present",
7239 e
->symtree
->n
.sym
->name
);
7240 else if (attr
.proc_pointer
&& !e
->value
.function
.actual
7241 && (fsym
== NULL
|| !fsym_attr
.proc_pointer
))
7242 msg
= xasprintf ("Proc-pointer actual argument '%s' is not "
7243 "associated or not present",
7244 e
->symtree
->n
.sym
->name
);
7246 goto end_pointer_check
;
7248 present
= gfc_conv_expr_present (e
->symtree
->n
.sym
);
7249 type
= TREE_TYPE (present
);
7250 present
= fold_build2_loc (input_location
, EQ_EXPR
,
7251 logical_type_node
, present
,
7253 null_pointer_node
));
7254 type
= TREE_TYPE (parmse
.expr
);
7255 null_ptr
= fold_build2_loc (input_location
, EQ_EXPR
,
7256 logical_type_node
, parmse
.expr
,
7258 null_pointer_node
));
7259 cond
= fold_build2_loc (input_location
, TRUTH_ORIF_EXPR
,
7260 logical_type_node
, present
, null_ptr
);
7264 if (attr
.allocatable
7265 && (fsym
== NULL
|| !fsym_attr
.allocatable
))
7266 msg
= xasprintf ("Allocatable actual argument '%s' is not "
7267 "allocated", e
->symtree
->n
.sym
->name
);
7268 else if (attr
.pointer
7269 && (fsym
== NULL
|| !fsym_attr
.pointer
))
7270 msg
= xasprintf ("Pointer actual argument '%s' is not "
7271 "associated", e
->symtree
->n
.sym
->name
);
7272 else if (attr
.proc_pointer
&& !e
->value
.function
.actual
7273 && (fsym
== NULL
|| !fsym_attr
.proc_pointer
))
7274 msg
= xasprintf ("Proc-pointer actual argument '%s' is not "
7275 "associated", e
->symtree
->n
.sym
->name
);
7277 goto end_pointer_check
;
7280 if (fsym
&& fsym
->ts
.type
== BT_CLASS
)
7282 if (POINTER_TYPE_P (TREE_TYPE (tmp
)))
7283 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
7284 tmp
= gfc_class_data_get (tmp
);
7285 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp
)))
7286 tmp
= gfc_conv_descriptor_data_get (tmp
);
7289 /* If the argument is passed by value, we need to strip the
7291 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
7292 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
7294 cond
= fold_build2_loc (input_location
, EQ_EXPR
,
7295 logical_type_node
, tmp
,
7296 fold_convert (TREE_TYPE (tmp
),
7297 null_pointer_node
));
7300 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, &e
->where
,
7306 /* Deferred length dummies pass the character length by reference
7307 so that the value can be returned. */
7308 if (parmse
.string_length
&& fsym
&& fsym
->ts
.deferred
)
7310 if (INDIRECT_REF_P (parmse
.string_length
))
7311 /* In chains of functions/procedure calls the string_length already
7312 is a pointer to the variable holding the length. Therefore
7313 remove the deref on call. */
7314 parmse
.string_length
= TREE_OPERAND (parmse
.string_length
, 0);
7317 tmp
= parmse
.string_length
;
7318 if (!VAR_P (tmp
) && TREE_CODE (tmp
) != COMPONENT_REF
)
7319 tmp
= gfc_evaluate_now (parmse
.string_length
, &se
->pre
);
7320 parmse
.string_length
= gfc_build_addr_expr (NULL_TREE
, tmp
);
7324 /* Character strings are passed as two parameters, a length and a
7325 pointer - except for Bind(c) which only passes the pointer.
7326 An unlimited polymorphic formal argument likewise does not
7328 if (parmse
.string_length
!= NULL_TREE
7329 && !sym
->attr
.is_bind_c
7330 && !(fsym
&& UNLIMITED_POLY (fsym
)))
7331 vec_safe_push (stringargs
, parmse
.string_length
);
7333 /* When calling __copy for character expressions to unlimited
7334 polymorphic entities, the dst argument needs a string length. */
7335 if (sym
->name
[0] == '_' && e
&& e
->ts
.type
== BT_CHARACTER
7336 && startswith (sym
->name
, "__vtab_CHARACTER")
7337 && arg
->next
&& arg
->next
->expr
7338 && (arg
->next
->expr
->ts
.type
== BT_DERIVED
7339 || arg
->next
->expr
->ts
.type
== BT_CLASS
)
7340 && arg
->next
->expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
)
7341 vec_safe_push (stringargs
, parmse
.string_length
);
7343 /* For descriptorless coarrays and assumed-shape coarray dummies, we
7344 pass the token and the offset as additional arguments. */
7345 if (fsym
&& e
== NULL
&& flag_coarray
== GFC_FCOARRAY_LIB
7346 && ((fsym
->ts
.type
!= BT_CLASS
&& fsym
->attr
.codimension
7347 && !fsym
->attr
.allocatable
)
7348 || (fsym
->ts
.type
== BT_CLASS
7349 && CLASS_DATA (fsym
)->attr
.codimension
7350 && !CLASS_DATA (fsym
)->attr
.allocatable
)))
7352 /* Token and offset. */
7353 vec_safe_push (stringargs
, null_pointer_node
);
7354 vec_safe_push (stringargs
, build_int_cst (gfc_array_index_type
, 0));
7355 gcc_assert (fsym
->attr
.optional
);
7357 else if (fsym
&& flag_coarray
== GFC_FCOARRAY_LIB
7358 && ((fsym
->ts
.type
!= BT_CLASS
&& fsym
->attr
.codimension
7359 && !fsym
->attr
.allocatable
)
7360 || (fsym
->ts
.type
== BT_CLASS
7361 && CLASS_DATA (fsym
)->attr
.codimension
7362 && !CLASS_DATA (fsym
)->attr
.allocatable
)))
7364 tree caf_decl
, caf_type
;
7367 caf_decl
= gfc_get_tree_for_caf_expr (e
);
7368 caf_type
= TREE_TYPE (caf_decl
);
7370 if (GFC_DESCRIPTOR_TYPE_P (caf_type
)
7371 && (GFC_TYPE_ARRAY_AKIND (caf_type
) == GFC_ARRAY_ALLOCATABLE
7372 || GFC_TYPE_ARRAY_AKIND (caf_type
) == GFC_ARRAY_POINTER
))
7373 tmp
= gfc_conv_descriptor_token (caf_decl
);
7374 else if (DECL_LANG_SPECIFIC (caf_decl
)
7375 && GFC_DECL_TOKEN (caf_decl
) != NULL_TREE
)
7376 tmp
= GFC_DECL_TOKEN (caf_decl
);
7379 gcc_assert (GFC_ARRAY_TYPE_P (caf_type
)
7380 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
) != NULL_TREE
);
7381 tmp
= GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
);
7384 vec_safe_push (stringargs
, tmp
);
7386 if (GFC_DESCRIPTOR_TYPE_P (caf_type
)
7387 && GFC_TYPE_ARRAY_AKIND (caf_type
) == GFC_ARRAY_ALLOCATABLE
)
7388 offset
= build_int_cst (gfc_array_index_type
, 0);
7389 else if (DECL_LANG_SPECIFIC (caf_decl
)
7390 && GFC_DECL_CAF_OFFSET (caf_decl
) != NULL_TREE
)
7391 offset
= GFC_DECL_CAF_OFFSET (caf_decl
);
7392 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type
) != NULL_TREE
)
7393 offset
= GFC_TYPE_ARRAY_CAF_OFFSET (caf_type
);
7395 offset
= build_int_cst (gfc_array_index_type
, 0);
7397 if (GFC_DESCRIPTOR_TYPE_P (caf_type
))
7398 tmp
= gfc_conv_descriptor_data_get (caf_decl
);
7401 gcc_assert (POINTER_TYPE_P (caf_type
));
7405 tmp2
= fsym
->ts
.type
== BT_CLASS
7406 ? gfc_class_data_get (parmse
.expr
) : parmse
.expr
;
7407 if ((fsym
->ts
.type
!= BT_CLASS
7408 && (fsym
->as
->type
== AS_ASSUMED_SHAPE
7409 || fsym
->as
->type
== AS_ASSUMED_RANK
))
7410 || (fsym
->ts
.type
== BT_CLASS
7411 && (CLASS_DATA (fsym
)->as
->type
== AS_ASSUMED_SHAPE
7412 || CLASS_DATA (fsym
)->as
->type
== AS_ASSUMED_RANK
)))
7414 if (fsym
->ts
.type
== BT_CLASS
)
7415 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2
)));
7418 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2
)));
7419 tmp2
= build_fold_indirect_ref_loc (input_location
, tmp2
);
7421 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2
)));
7422 tmp2
= gfc_conv_descriptor_data_get (tmp2
);
7424 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2
)))
7425 tmp2
= gfc_conv_descriptor_data_get (tmp2
);
7428 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2
)));
7431 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
7432 gfc_array_index_type
,
7433 fold_convert (gfc_array_index_type
, tmp2
),
7434 fold_convert (gfc_array_index_type
, tmp
));
7435 offset
= fold_build2_loc (input_location
, PLUS_EXPR
,
7436 gfc_array_index_type
, offset
, tmp
);
7438 vec_safe_push (stringargs
, offset
);
7441 vec_safe_push (arglist
, parmse
.expr
);
7443 gfc_add_block_to_block (&se
->pre
, &clobbers
);
7444 gfc_finish_interface_mapping (&mapping
, &se
->pre
, &se
->post
);
7448 else if (sym
->ts
.type
== BT_CLASS
)
7449 ts
= CLASS_DATA (sym
)->ts
;
7453 if (ts
.type
== BT_CHARACTER
&& sym
->attr
.is_bind_c
)
7454 se
->string_length
= build_int_cst (gfc_charlen_type_node
, 1);
7455 else if (ts
.type
== BT_CHARACTER
)
7457 if (ts
.u
.cl
->length
== NULL
)
7459 /* Assumed character length results are not allowed by C418 of the 2003
7460 standard and are trapped in resolve.cc; except in the case of SPREAD
7461 (and other intrinsics?) and dummy functions. In the case of SPREAD,
7462 we take the character length of the first argument for the result.
7463 For dummies, we have to look through the formal argument list for
7464 this function and use the character length found there.*/
7466 cl
.backend_decl
= gfc_create_var (gfc_charlen_type_node
, "slen");
7467 else if (!sym
->attr
.dummy
)
7468 cl
.backend_decl
= (*stringargs
)[0];
7471 formal
= gfc_sym_get_dummy_args (sym
->ns
->proc_name
);
7472 for (; formal
; formal
= formal
->next
)
7473 if (strcmp (formal
->sym
->name
, sym
->name
) == 0)
7474 cl
.backend_decl
= formal
->sym
->ts
.u
.cl
->backend_decl
;
7476 len
= cl
.backend_decl
;
7482 /* Calculate the length of the returned string. */
7483 gfc_init_se (&parmse
, NULL
);
7484 if (need_interface_mapping
)
7485 gfc_apply_interface_mapping (&mapping
, &parmse
, ts
.u
.cl
->length
);
7487 gfc_conv_expr (&parmse
, ts
.u
.cl
->length
);
7488 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
7489 gfc_add_block_to_block (&se
->post
, &parmse
.post
);
7491 /* TODO: It would be better to have the charlens as
7492 gfc_charlen_type_node already when the interface is
7493 created instead of converting it here (see PR 84615). */
7494 tmp
= fold_build2_loc (input_location
, MAX_EXPR
,
7495 gfc_charlen_type_node
,
7496 fold_convert (gfc_charlen_type_node
, tmp
),
7497 build_zero_cst (gfc_charlen_type_node
));
7498 cl
.backend_decl
= tmp
;
7501 /* Set up a charlen structure for it. */
7506 len
= cl
.backend_decl
;
7509 byref
= (comp
&& (comp
->attr
.dimension
7510 || (comp
->ts
.type
== BT_CHARACTER
&& !sym
->attr
.is_bind_c
)))
7511 || (!comp
&& gfc_return_by_reference (sym
));
7514 if (se
->direct_byref
)
7516 /* Sometimes, too much indirection can be applied; e.g. for
7517 function_result = array_valued_recursive_function. */
7518 if (TREE_TYPE (TREE_TYPE (se
->expr
))
7519 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
)))
7520 && GFC_DESCRIPTOR_TYPE_P
7521 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
)))))
7522 se
->expr
= build_fold_indirect_ref_loc (input_location
,
7525 /* If the lhs of an assignment x = f(..) is allocatable and
7526 f2003 is allowed, we must do the automatic reallocation.
7527 TODO - deal with intrinsics, without using a temporary. */
7528 if (flag_realloc_lhs
7529 && se
->ss
&& se
->ss
->loop_chain
7530 && se
->ss
->loop_chain
->is_alloc_lhs
7531 && !expr
->value
.function
.isym
7532 && sym
->result
->as
!= NULL
)
7534 /* Evaluate the bounds of the result, if known. */
7535 gfc_set_loop_bounds_from_array_spec (&mapping
, se
,
7538 /* Perform the automatic reallocation. */
7539 tmp
= gfc_alloc_allocatable_for_assignment (se
->loop
,
7541 gfc_add_expr_to_block (&se
->pre
, tmp
);
7543 /* Pass the temporary as the first argument. */
7544 result
= info
->descriptor
;
7547 result
= build_fold_indirect_ref_loc (input_location
,
7549 vec_safe_push (retargs
, se
->expr
);
7551 else if (comp
&& comp
->attr
.dimension
)
7553 gcc_assert (se
->loop
&& info
);
7555 /* Set the type of the array. */
7556 tmp
= gfc_typenode_for_spec (&comp
->ts
);
7557 gcc_assert (se
->ss
->dimen
== se
->loop
->dimen
);
7559 /* Evaluate the bounds of the result, if known. */
7560 gfc_set_loop_bounds_from_array_spec (&mapping
, se
, comp
->as
);
7562 /* If the lhs of an assignment x = f(..) is allocatable and
7563 f2003 is allowed, we must not generate the function call
7564 here but should just send back the results of the mapping.
7565 This is signalled by the function ss being flagged. */
7566 if (flag_realloc_lhs
&& se
->ss
&& se
->ss
->is_alloc_lhs
)
7568 gfc_free_interface_mapping (&mapping
);
7569 return has_alternate_specifier
;
7572 /* Create a temporary to store the result. In case the function
7573 returns a pointer, the temporary will be a shallow copy and
7574 mustn't be deallocated. */
7575 callee_alloc
= comp
->attr
.allocatable
|| comp
->attr
.pointer
;
7576 gfc_trans_create_temp_array (&se
->pre
, &se
->post
, se
->ss
,
7577 tmp
, NULL_TREE
, false,
7578 !comp
->attr
.pointer
, callee_alloc
,
7579 &se
->ss
->info
->expr
->where
);
7581 /* Pass the temporary as the first argument. */
7582 result
= info
->descriptor
;
7583 tmp
= gfc_build_addr_expr (NULL_TREE
, result
);
7584 vec_safe_push (retargs
, tmp
);
7586 else if (!comp
&& sym
->result
->attr
.dimension
)
7588 gcc_assert (se
->loop
&& info
);
7590 /* Set the type of the array. */
7591 tmp
= gfc_typenode_for_spec (&ts
);
7592 gcc_assert (se
->ss
->dimen
== se
->loop
->dimen
);
7594 /* Evaluate the bounds of the result, if known. */
7595 gfc_set_loop_bounds_from_array_spec (&mapping
, se
, sym
->result
->as
);
7597 /* If the lhs of an assignment x = f(..) is allocatable and
7598 f2003 is allowed, we must not generate the function call
7599 here but should just send back the results of the mapping.
7600 This is signalled by the function ss being flagged. */
7601 if (flag_realloc_lhs
&& se
->ss
&& se
->ss
->is_alloc_lhs
)
7603 gfc_free_interface_mapping (&mapping
);
7604 return has_alternate_specifier
;
7607 /* Create a temporary to store the result. In case the function
7608 returns a pointer, the temporary will be a shallow copy and
7609 mustn't be deallocated. */
7610 callee_alloc
= sym
->attr
.allocatable
|| sym
->attr
.pointer
;
7611 gfc_trans_create_temp_array (&se
->pre
, &se
->post
, se
->ss
,
7612 tmp
, NULL_TREE
, false,
7613 !sym
->attr
.pointer
, callee_alloc
,
7614 &se
->ss
->info
->expr
->where
);
7616 /* Pass the temporary as the first argument. */
7617 result
= info
->descriptor
;
7618 tmp
= gfc_build_addr_expr (NULL_TREE
, result
);
7619 vec_safe_push (retargs
, tmp
);
7621 else if (ts
.type
== BT_CHARACTER
)
7623 /* Pass the string length. */
7624 type
= gfc_get_character_type (ts
.kind
, ts
.u
.cl
);
7625 type
= build_pointer_type (type
);
7627 /* Emit a DECL_EXPR for the VLA type. */
7628 tmp
= TREE_TYPE (type
);
7630 && TREE_CODE (TYPE_SIZE (tmp
)) != INTEGER_CST
)
7632 tmp
= build_decl (input_location
, TYPE_DECL
, NULL_TREE
, tmp
);
7633 DECL_ARTIFICIAL (tmp
) = 1;
7634 DECL_IGNORED_P (tmp
) = 1;
7635 tmp
= fold_build1_loc (input_location
, DECL_EXPR
,
7636 TREE_TYPE (tmp
), tmp
);
7637 gfc_add_expr_to_block (&se
->pre
, tmp
);
7640 /* Return an address to a char[0:len-1]* temporary for
7641 character pointers. */
7642 if ((!comp
&& (sym
->attr
.pointer
|| sym
->attr
.allocatable
))
7643 || (comp
&& (comp
->attr
.pointer
|| comp
->attr
.allocatable
)))
7645 var
= gfc_create_var (type
, "pstr");
7647 if ((!comp
&& sym
->attr
.allocatable
)
7648 || (comp
&& comp
->attr
.allocatable
))
7650 gfc_add_modify (&se
->pre
, var
,
7651 fold_convert (TREE_TYPE (var
),
7652 null_pointer_node
));
7653 tmp
= gfc_call_free (var
);
7654 gfc_add_expr_to_block (&se
->post
, tmp
);
7657 /* Provide an address expression for the function arguments. */
7658 var
= gfc_build_addr_expr (NULL_TREE
, var
);
7661 var
= gfc_conv_string_tmp (se
, type
, len
);
7663 vec_safe_push (retargs
, var
);
7667 gcc_assert (flag_f2c
&& ts
.type
== BT_COMPLEX
);
7669 type
= gfc_get_complex_type (ts
.kind
);
7670 var
= gfc_build_addr_expr (NULL_TREE
, gfc_create_var (type
, "cmplx"));
7671 vec_safe_push (retargs
, var
);
7674 /* Add the string length to the argument list. */
7675 if (ts
.type
== BT_CHARACTER
&& ts
.deferred
)
7679 tmp
= gfc_evaluate_now (len
, &se
->pre
);
7680 TREE_STATIC (tmp
) = 1;
7681 gfc_add_modify (&se
->pre
, tmp
,
7682 build_int_cst (TREE_TYPE (tmp
), 0));
7683 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
7684 vec_safe_push (retargs
, tmp
);
7686 else if (ts
.type
== BT_CHARACTER
)
7687 vec_safe_push (retargs
, len
);
7689 gfc_free_interface_mapping (&mapping
);
7691 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
7692 arglen
= (vec_safe_length (arglist
) + vec_safe_length (optionalargs
)
7693 + vec_safe_length (stringargs
) + vec_safe_length (append_args
));
7694 vec_safe_reserve (retargs
, arglen
);
7696 /* Add the return arguments. */
7697 vec_safe_splice (retargs
, arglist
);
7699 /* Add the hidden present status for optional+value to the arguments. */
7700 vec_safe_splice (retargs
, optionalargs
);
7702 /* Add the hidden string length parameters to the arguments. */
7703 vec_safe_splice (retargs
, stringargs
);
7705 /* We may want to append extra arguments here. This is used e.g. for
7706 calls to libgfortran_matmul_??, which need extra information. */
7707 vec_safe_splice (retargs
, append_args
);
7711 /* Generate the actual call. */
7712 if (base_object
== NULL_TREE
)
7713 conv_function_val (se
, sym
, expr
, args
);
7715 conv_base_obj_fcn_val (se
, base_object
, expr
);
7717 /* If there are alternate return labels, function type should be
7718 integer. Can't modify the type in place though, since it can be shared
7719 with other functions. For dummy arguments, the typing is done to
7720 this result, even if it has to be repeated for each call. */
7721 if (has_alternate_specifier
7722 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
))) != integer_type_node
)
7724 if (!sym
->attr
.dummy
)
7726 TREE_TYPE (sym
->backend_decl
)
7727 = build_function_type (integer_type_node
,
7728 TYPE_ARG_TYPES (TREE_TYPE (sym
->backend_decl
)));
7729 se
->expr
= gfc_build_addr_expr (NULL_TREE
, sym
->backend_decl
);
7732 TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
))) = integer_type_node
;
7735 fntype
= TREE_TYPE (TREE_TYPE (se
->expr
));
7736 se
->expr
= build_call_vec (TREE_TYPE (fntype
), se
->expr
, arglist
);
7738 /* Allocatable scalar function results must be freed and nullified
7739 after use. This necessitates the creation of a temporary to
7740 hold the result to prevent duplicate calls. */
7741 if (!byref
&& sym
->ts
.type
!= BT_CHARACTER
7742 && ((sym
->attr
.allocatable
&& !sym
->attr
.dimension
&& !comp
)
7743 || (comp
&& comp
->attr
.allocatable
&& !comp
->attr
.dimension
)))
7745 tmp
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
7746 gfc_add_modify (&se
->pre
, tmp
, se
->expr
);
7748 tmp
= gfc_call_free (tmp
);
7749 gfc_add_expr_to_block (&post
, tmp
);
7750 gfc_add_modify (&post
, se
->expr
, build_int_cst (TREE_TYPE (se
->expr
), 0));
7753 /* If we have a pointer function, but we don't want a pointer, e.g.
7756 where f is pointer valued, we have to dereference the result. */
7757 if (!se
->want_pointer
&& !byref
7758 && ((!comp
&& (sym
->attr
.pointer
|| sym
->attr
.allocatable
))
7759 || (comp
&& (comp
->attr
.pointer
|| comp
->attr
.allocatable
))))
7760 se
->expr
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
7762 /* f2c calling conventions require a scalar default real function to
7763 return a double precision result. Convert this back to default
7764 real. We only care about the cases that can happen in Fortran 77.
7766 if (flag_f2c
&& sym
->ts
.type
== BT_REAL
7767 && sym
->ts
.kind
== gfc_default_real_kind
7768 && !sym
->attr
.always_explicit
)
7769 se
->expr
= fold_convert (gfc_get_real_type (sym
->ts
.kind
), se
->expr
);
7771 /* A pure function may still have side-effects - it may modify its
7773 TREE_SIDE_EFFECTS (se
->expr
) = 1;
7775 if (!sym
->attr
.pure
)
7776 TREE_SIDE_EFFECTS (se
->expr
) = 1;
7781 /* Add the function call to the pre chain. There is no expression. */
7782 gfc_add_expr_to_block (&se
->pre
, se
->expr
);
7783 se
->expr
= NULL_TREE
;
7785 if (!se
->direct_byref
)
7787 if ((sym
->attr
.dimension
&& !comp
) || (comp
&& comp
->attr
.dimension
))
7789 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
7791 /* Check the data pointer hasn't been modified. This would
7792 happen in a function returning a pointer. */
7793 tmp
= gfc_conv_descriptor_data_get (info
->descriptor
);
7794 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
7797 gfc_trans_runtime_check (true, false, tmp
, &se
->pre
, NULL
,
7800 se
->expr
= info
->descriptor
;
7801 /* Bundle in the string length. */
7802 se
->string_length
= len
;
7804 else if (ts
.type
== BT_CHARACTER
)
7806 /* Dereference for character pointer results. */
7807 if ((!comp
&& (sym
->attr
.pointer
|| sym
->attr
.allocatable
))
7808 || (comp
&& (comp
->attr
.pointer
|| comp
->attr
.allocatable
)))
7809 se
->expr
= build_fold_indirect_ref_loc (input_location
, var
);
7813 se
->string_length
= len
;
7817 gcc_assert (ts
.type
== BT_COMPLEX
&& flag_f2c
);
7818 se
->expr
= build_fold_indirect_ref_loc (input_location
, var
);
7823 /* Associate the rhs class object's meta-data with the result, when the
7824 result is a temporary. */
7825 if (args
&& args
->expr
&& args
->expr
->ts
.type
== BT_CLASS
7826 && sym
->ts
.type
== BT_CLASS
&& result
!= NULL_TREE
&& DECL_P (result
)
7827 && !GFC_CLASS_TYPE_P (TREE_TYPE (result
)))
7830 gfc_expr
*class_expr
= gfc_find_and_cut_at_last_class_ref (args
->expr
);
7832 gfc_init_se (&parmse
, NULL
);
7833 parmse
.data_not_needed
= 1;
7834 gfc_conv_expr (&parmse
, class_expr
);
7835 if (!DECL_LANG_SPECIFIC (result
))
7836 gfc_allocate_lang_decl (result
);
7837 GFC_DECL_SAVED_DESCRIPTOR (result
) = parmse
.expr
;
7838 gfc_free_expr (class_expr
);
7839 /* -fcheck= can add diagnostic code, which has to be placed before
7841 if (parmse
.pre
.head
!= NULL
)
7842 gfc_add_expr_to_block (&se
->pre
, parmse
.pre
.head
);
7843 gcc_assert (parmse
.post
.head
== NULL_TREE
);
7846 /* Follow the function call with the argument post block. */
7849 gfc_add_block_to_block (&se
->pre
, &post
);
7851 /* Transformational functions of derived types with allocatable
7852 components must have the result allocatable components copied when the
7853 argument is actually given. */
7854 arg
= expr
->value
.function
.actual
;
7855 if (result
&& arg
&& expr
->rank
7856 && expr
->value
.function
.isym
7857 && expr
->value
.function
.isym
->transformational
7859 && arg
->expr
->ts
.type
== BT_DERIVED
7860 && arg
->expr
->ts
.u
.derived
->attr
.alloc_comp
)
7863 /* Copy the allocatable components. We have to use a
7864 temporary here to prevent source allocatable components
7865 from being corrupted. */
7866 tmp2
= gfc_evaluate_now (result
, &se
->pre
);
7867 tmp
= gfc_copy_alloc_comp (arg
->expr
->ts
.u
.derived
,
7868 result
, tmp2
, expr
->rank
, 0);
7869 gfc_add_expr_to_block (&se
->pre
, tmp
);
7870 tmp
= gfc_copy_allocatable_data (result
, tmp2
, TREE_TYPE(tmp2
),
7872 gfc_add_expr_to_block (&se
->pre
, tmp
);
7874 /* Finally free the temporary's data field. */
7875 tmp
= gfc_conv_descriptor_data_get (tmp2
);
7876 tmp
= gfc_deallocate_with_status (tmp
, NULL_TREE
, NULL_TREE
,
7877 NULL_TREE
, NULL_TREE
, true,
7878 NULL
, GFC_CAF_COARRAY_NOCOARRAY
);
7879 gfc_add_expr_to_block (&se
->pre
, tmp
);
7884 /* For a function with a class array result, save the result as
7885 a temporary, set the info fields needed by the scalarizer and
7886 call the finalization function of the temporary. Note that the
7887 nullification of allocatable components needed by the result
7888 is done in gfc_trans_assignment_1. */
7889 if (expr
&& ((gfc_is_class_array_function (expr
)
7890 && se
->ss
&& se
->ss
->loop
)
7891 || gfc_is_alloc_class_scalar_function (expr
))
7892 && se
->expr
&& GFC_CLASS_TYPE_P (TREE_TYPE (se
->expr
))
7893 && expr
->must_finalize
)
7898 if (se
->ss
&& se
->ss
->loop
)
7900 gfc_add_block_to_block (&se
->ss
->loop
->pre
, &se
->pre
);
7901 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->ss
->loop
->pre
);
7902 tmp
= gfc_class_data_get (se
->expr
);
7903 info
->descriptor
= tmp
;
7904 info
->data
= gfc_conv_descriptor_data_get (tmp
);
7905 info
->offset
= gfc_conv_descriptor_offset_get (tmp
);
7906 for (n
= 0; n
< se
->ss
->loop
->dimen
; n
++)
7908 tree dim
= gfc_rank_cst
[n
];
7909 se
->ss
->loop
->to
[n
] = gfc_conv_descriptor_ubound_get (tmp
, dim
);
7910 se
->ss
->loop
->from
[n
] = gfc_conv_descriptor_lbound_get (tmp
, dim
);
7915 /* TODO Eliminate the doubling of temporaries. This
7916 one is necessary to ensure no memory leakage. */
7917 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
7918 tmp
= gfc_class_data_get (se
->expr
);
7919 tmp
= gfc_conv_scalar_to_descriptor (se
, tmp
,
7920 CLASS_DATA (expr
->value
.function
.esym
->result
)->attr
);
7923 if ((gfc_is_class_array_function (expr
)
7924 || gfc_is_alloc_class_scalar_function (expr
))
7925 && CLASS_DATA (expr
->value
.function
.esym
->result
)->attr
.pointer
)
7926 goto no_finalization
;
7928 final_fndecl
= gfc_class_vtab_final_get (se
->expr
);
7929 is_final
= fold_build2_loc (input_location
, NE_EXPR
,
7932 fold_convert (TREE_TYPE (final_fndecl
),
7933 null_pointer_node
));
7934 final_fndecl
= build_fold_indirect_ref_loc (input_location
,
7936 tmp
= build_call_expr_loc (input_location
,
7938 gfc_build_addr_expr (NULL
, tmp
),
7939 gfc_class_vtab_size_get (se
->expr
),
7940 boolean_false_node
);
7941 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
7942 void_type_node
, is_final
, tmp
,
7943 build_empty_stmt (input_location
));
7945 if (se
->ss
&& se
->ss
->loop
)
7947 gfc_prepend_expr_to_block (&se
->ss
->loop
->post
, tmp
);
7948 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
7951 fold_convert (TREE_TYPE (info
->data
),
7952 null_pointer_node
));
7953 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
7954 void_type_node
, tmp
,
7955 gfc_call_free (info
->data
),
7956 build_empty_stmt (input_location
));
7957 gfc_add_expr_to_block (&se
->ss
->loop
->post
, tmp
);
7962 gfc_prepend_expr_to_block (&se
->post
, tmp
);
7963 classdata
= gfc_class_data_get (se
->expr
);
7964 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
7967 fold_convert (TREE_TYPE (classdata
),
7968 null_pointer_node
));
7969 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
7970 void_type_node
, tmp
,
7971 gfc_call_free (classdata
),
7972 build_empty_stmt (input_location
));
7973 gfc_add_expr_to_block (&se
->post
, tmp
);
7978 gfc_add_block_to_block (&se
->post
, &post
);
7981 return has_alternate_specifier
;
7985 /* Fill a character string with spaces. */
7988 fill_with_spaces (tree start
, tree type
, tree size
)
7990 stmtblock_t block
, loop
;
7991 tree i
, el
, exit_label
, cond
, tmp
;
7993 /* For a simple char type, we can call memset(). */
7994 if (compare_tree_int (TYPE_SIZE_UNIT (type
), 1) == 0)
7995 return build_call_expr_loc (input_location
,
7996 builtin_decl_explicit (BUILT_IN_MEMSET
),
7998 build_int_cst (gfc_get_int_type (gfc_c_int_kind
),
7999 lang_hooks
.to_target_charset (' ')),
8000 fold_convert (size_type_node
, size
));
8002 /* Otherwise, we use a loop:
8003 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
8007 /* Initialize variables. */
8008 gfc_init_block (&block
);
8009 i
= gfc_create_var (sizetype
, "i");
8010 gfc_add_modify (&block
, i
, fold_convert (sizetype
, size
));
8011 el
= gfc_create_var (build_pointer_type (type
), "el");
8012 gfc_add_modify (&block
, el
, fold_convert (TREE_TYPE (el
), start
));
8013 exit_label
= gfc_build_label_decl (NULL_TREE
);
8014 TREE_USED (exit_label
) = 1;
8018 gfc_init_block (&loop
);
8020 /* Exit condition. */
8021 cond
= fold_build2_loc (input_location
, LE_EXPR
, logical_type_node
, i
,
8022 build_zero_cst (sizetype
));
8023 tmp
= build1_v (GOTO_EXPR
, exit_label
);
8024 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
, tmp
,
8025 build_empty_stmt (input_location
));
8026 gfc_add_expr_to_block (&loop
, tmp
);
8029 gfc_add_modify (&loop
,
8030 fold_build1_loc (input_location
, INDIRECT_REF
, type
, el
),
8031 build_int_cst (type
, lang_hooks
.to_target_charset (' ')));
8033 /* Increment loop variables. */
8034 gfc_add_modify (&loop
, i
,
8035 fold_build2_loc (input_location
, MINUS_EXPR
, sizetype
, i
,
8036 TYPE_SIZE_UNIT (type
)));
8037 gfc_add_modify (&loop
, el
,
8038 fold_build_pointer_plus_loc (input_location
,
8039 el
, TYPE_SIZE_UNIT (type
)));
8041 /* Making the loop... actually loop! */
8042 tmp
= gfc_finish_block (&loop
);
8043 tmp
= build1_v (LOOP_EXPR
, tmp
);
8044 gfc_add_expr_to_block (&block
, tmp
);
8046 /* The exit label. */
8047 tmp
= build1_v (LABEL_EXPR
, exit_label
);
8048 gfc_add_expr_to_block (&block
, tmp
);
8051 return gfc_finish_block (&block
);
8055 /* Generate code to copy a string. */
8058 gfc_trans_string_copy (stmtblock_t
* block
, tree dlength
, tree dest
,
8059 int dkind
, tree slength
, tree src
, int skind
)
8061 tree tmp
, dlen
, slen
;
8070 stmtblock_t tempblock
;
8072 gcc_assert (dkind
== skind
);
8074 if (slength
!= NULL_TREE
)
8076 slen
= gfc_evaluate_now (fold_convert (gfc_charlen_type_node
, slength
), block
);
8077 ssc
= gfc_string_to_single_character (slen
, src
, skind
);
8081 slen
= build_one_cst (gfc_charlen_type_node
);
8085 if (dlength
!= NULL_TREE
)
8087 dlen
= gfc_evaluate_now (fold_convert (gfc_charlen_type_node
, dlength
), block
);
8088 dsc
= gfc_string_to_single_character (dlen
, dest
, dkind
);
8092 dlen
= build_one_cst (gfc_charlen_type_node
);
8096 /* Assign directly if the types are compatible. */
8097 if (dsc
!= NULL_TREE
&& ssc
!= NULL_TREE
8098 && TREE_TYPE (dsc
) == TREE_TYPE (ssc
))
8100 gfc_add_modify (block
, dsc
, ssc
);
8104 /* The string copy algorithm below generates code like
8108 if (srclen < destlen)
8110 memmove (dest, src, srclen);
8112 memset (&dest[srclen], ' ', destlen - srclen);
8116 // Truncate if too long.
8117 memmove (dest, src, destlen);
8122 /* Do nothing if the destination length is zero. */
8123 cond
= fold_build2_loc (input_location
, GT_EXPR
, logical_type_node
, dlen
,
8124 build_zero_cst (TREE_TYPE (dlen
)));
8126 /* For non-default character kinds, we have to multiply the string
8127 length by the base type size. */
8128 chartype
= gfc_get_char_type (dkind
);
8129 slen
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (slen
),
8131 fold_convert (TREE_TYPE (slen
),
8132 TYPE_SIZE_UNIT (chartype
)));
8133 dlen
= fold_build2_loc (input_location
, MULT_EXPR
, TREE_TYPE (dlen
),
8135 fold_convert (TREE_TYPE (dlen
),
8136 TYPE_SIZE_UNIT (chartype
)));
8138 if (dlength
&& POINTER_TYPE_P (TREE_TYPE (dest
)))
8139 dest
= fold_convert (pvoid_type_node
, dest
);
8141 dest
= gfc_build_addr_expr (pvoid_type_node
, dest
);
8143 if (slength
&& POINTER_TYPE_P (TREE_TYPE (src
)))
8144 src
= fold_convert (pvoid_type_node
, src
);
8146 src
= gfc_build_addr_expr (pvoid_type_node
, src
);
8148 /* Truncate string if source is too long. */
8149 cond2
= fold_build2_loc (input_location
, LT_EXPR
, logical_type_node
, slen
,
8152 /* Pre-evaluate pointers unless one of the IF arms will be optimized away. */
8153 if (!CONSTANT_CLASS_P (cond2
))
8155 dest
= gfc_evaluate_now (dest
, block
);
8156 src
= gfc_evaluate_now (src
, block
);
8159 /* Copy and pad with spaces. */
8160 tmp3
= build_call_expr_loc (input_location
,
8161 builtin_decl_explicit (BUILT_IN_MEMMOVE
),
8163 fold_convert (size_type_node
, slen
));
8165 /* Wstringop-overflow appears at -O3 even though this warning is not
8166 explicitly available in fortran nor can it be switched off. If the
8167 source length is a constant, its negative appears as a very large
8168 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
8169 the result of the MINUS_EXPR suppresses this spurious warning. */
8170 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
8171 TREE_TYPE(dlen
), dlen
, slen
);
8172 if (slength
&& TREE_CONSTANT (slength
))
8173 tmp
= gfc_evaluate_now (tmp
, block
);
8175 tmp4
= fold_build_pointer_plus_loc (input_location
, dest
, slen
);
8176 tmp4
= fill_with_spaces (tmp4
, chartype
, tmp
);
8178 gfc_init_block (&tempblock
);
8179 gfc_add_expr_to_block (&tempblock
, tmp3
);
8180 gfc_add_expr_to_block (&tempblock
, tmp4
);
8181 tmp3
= gfc_finish_block (&tempblock
);
8183 /* The truncated memmove if the slen >= dlen. */
8184 tmp2
= build_call_expr_loc (input_location
,
8185 builtin_decl_explicit (BUILT_IN_MEMMOVE
),
8187 fold_convert (size_type_node
, dlen
));
8189 /* The whole copy_string function is there. */
8190 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond2
,
8192 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
, tmp
,
8193 build_empty_stmt (input_location
));
8194 gfc_add_expr_to_block (block
, tmp
);
8198 /* Translate a statement function.
8199 The value of a statement function reference is obtained by evaluating the
8200 expression using the values of the actual arguments for the values of the
8201 corresponding dummy arguments. */
8204 gfc_conv_statement_function (gfc_se
* se
, gfc_expr
* expr
)
8208 gfc_formal_arglist
*fargs
;
8209 gfc_actual_arglist
*args
;
8212 gfc_saved_var
*saved_vars
;
8218 sym
= expr
->symtree
->n
.sym
;
8219 args
= expr
->value
.function
.actual
;
8220 gfc_init_se (&lse
, NULL
);
8221 gfc_init_se (&rse
, NULL
);
8224 for (fargs
= gfc_sym_get_dummy_args (sym
); fargs
; fargs
= fargs
->next
)
8226 saved_vars
= XCNEWVEC (gfc_saved_var
, n
);
8227 temp_vars
= XCNEWVEC (tree
, n
);
8229 for (fargs
= gfc_sym_get_dummy_args (sym
), n
= 0; fargs
;
8230 fargs
= fargs
->next
, n
++)
8232 /* Each dummy shall be specified, explicitly or implicitly, to be
8234 gcc_assert (fargs
->sym
->attr
.dimension
== 0);
8237 if (fsym
->ts
.type
== BT_CHARACTER
)
8239 /* Copy string arguments. */
8242 gcc_assert (fsym
->ts
.u
.cl
&& fsym
->ts
.u
.cl
->length
8243 && fsym
->ts
.u
.cl
->length
->expr_type
== EXPR_CONSTANT
);
8245 /* Create a temporary to hold the value. */
8246 if (fsym
->ts
.u
.cl
->backend_decl
== NULL_TREE
)
8247 fsym
->ts
.u
.cl
->backend_decl
8248 = gfc_conv_constant_to_tree (fsym
->ts
.u
.cl
->length
);
8250 type
= gfc_get_character_type (fsym
->ts
.kind
, fsym
->ts
.u
.cl
);
8251 temp_vars
[n
] = gfc_create_var (type
, fsym
->name
);
8253 arglen
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
8255 gfc_conv_expr (&rse
, args
->expr
);
8256 gfc_conv_string_parameter (&rse
);
8257 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
8258 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
8260 gfc_trans_string_copy (&se
->pre
, arglen
, temp_vars
[n
], fsym
->ts
.kind
,
8261 rse
.string_length
, rse
.expr
, fsym
->ts
.kind
);
8262 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
8263 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
8267 /* For everything else, just evaluate the expression. */
8269 /* Create a temporary to hold the value. */
8270 type
= gfc_typenode_for_spec (&fsym
->ts
);
8271 temp_vars
[n
] = gfc_create_var (type
, fsym
->name
);
8273 gfc_conv_expr (&lse
, args
->expr
);
8275 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
8276 gfc_add_modify (&se
->pre
, temp_vars
[n
], lse
.expr
);
8277 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
8283 /* Use the temporary variables in place of the real ones. */
8284 for (fargs
= gfc_sym_get_dummy_args (sym
), n
= 0; fargs
;
8285 fargs
= fargs
->next
, n
++)
8286 gfc_shadow_sym (fargs
->sym
, temp_vars
[n
], &saved_vars
[n
]);
8288 gfc_conv_expr (se
, sym
->value
);
8290 if (sym
->ts
.type
== BT_CHARACTER
)
8292 gfc_conv_const_charlen (sym
->ts
.u
.cl
);
8294 /* Force the expression to the correct length. */
8295 if (!INTEGER_CST_P (se
->string_length
)
8296 || tree_int_cst_lt (se
->string_length
,
8297 sym
->ts
.u
.cl
->backend_decl
))
8299 type
= gfc_get_character_type (sym
->ts
.kind
, sym
->ts
.u
.cl
);
8300 tmp
= gfc_create_var (type
, sym
->name
);
8301 tmp
= gfc_build_addr_expr (build_pointer_type (type
), tmp
);
8302 gfc_trans_string_copy (&se
->pre
, sym
->ts
.u
.cl
->backend_decl
, tmp
,
8303 sym
->ts
.kind
, se
->string_length
, se
->expr
,
8307 se
->string_length
= sym
->ts
.u
.cl
->backend_decl
;
8310 /* Restore the original variables. */
8311 for (fargs
= gfc_sym_get_dummy_args (sym
), n
= 0; fargs
;
8312 fargs
= fargs
->next
, n
++)
8313 gfc_restore_sym (fargs
->sym
, &saved_vars
[n
]);
8319 /* Translate a function expression. */
8322 gfc_conv_function_expr (gfc_se
* se
, gfc_expr
* expr
)
8326 if (expr
->value
.function
.isym
)
8328 gfc_conv_intrinsic_function (se
, expr
);
8332 /* expr.value.function.esym is the resolved (specific) function symbol for
8333 most functions. However this isn't set for dummy procedures. */
8334 sym
= expr
->value
.function
.esym
;
8336 sym
= expr
->symtree
->n
.sym
;
8338 /* The IEEE_ARITHMETIC functions are caught here. */
8339 if (sym
->from_intmod
== INTMOD_IEEE_ARITHMETIC
)
8340 if (gfc_conv_ieee_arithmetic_function (se
, expr
))
8343 /* We distinguish statement functions from general functions to improve
8344 runtime performance. */
8345 if (sym
->attr
.proc
== PROC_ST_FUNCTION
)
8347 gfc_conv_statement_function (se
, expr
);
8351 gfc_conv_procedure_call (se
, sym
, expr
->value
.function
.actual
, expr
,
8356 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
8359 is_zero_initializer_p (gfc_expr
* expr
)
8361 if (expr
->expr_type
!= EXPR_CONSTANT
)
8364 /* We ignore constants with prescribed memory representations for now. */
8365 if (expr
->representation
.string
)
8368 switch (expr
->ts
.type
)
8371 return mpz_cmp_si (expr
->value
.integer
, 0) == 0;
8374 return mpfr_zero_p (expr
->value
.real
)
8375 && MPFR_SIGN (expr
->value
.real
) >= 0;
8378 return expr
->value
.logical
== 0;
8381 return mpfr_zero_p (mpc_realref (expr
->value
.complex))
8382 && MPFR_SIGN (mpc_realref (expr
->value
.complex)) >= 0
8383 && mpfr_zero_p (mpc_imagref (expr
->value
.complex))
8384 && MPFR_SIGN (mpc_imagref (expr
->value
.complex)) >= 0;
8394 gfc_conv_array_constructor_expr (gfc_se
* se
, gfc_expr
* expr
)
8399 gcc_assert (ss
!= NULL
&& ss
!= gfc_ss_terminator
);
8400 gcc_assert (ss
->info
->expr
== expr
&& ss
->info
->type
== GFC_SS_CONSTRUCTOR
);
8402 gfc_conv_tmp_array_ref (se
);
8406 /* Build a static initializer. EXPR is the expression for the initial value.
8407 The other parameters describe the variable of the component being
8408 initialized. EXPR may be null. */
8411 gfc_conv_initializer (gfc_expr
* expr
, gfc_typespec
* ts
, tree type
,
8412 bool array
, bool pointer
, bool procptr
)
8416 if (flag_coarray
!= GFC_FCOARRAY_LIB
&& ts
->type
== BT_DERIVED
8417 && ts
->u
.derived
->from_intmod
== INTMOD_ISO_FORTRAN_ENV
8418 && ts
->u
.derived
->intmod_sym_id
== ISOFORTRAN_EVENT_TYPE
)
8419 return build_constructor (type
, NULL
);
8421 if (!(expr
|| pointer
|| procptr
))
8424 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
8425 (these are the only two iso_c_binding derived types that can be
8426 used as initialization expressions). If so, we need to modify
8427 the 'expr' to be that for a (void *). */
8428 if (expr
!= NULL
&& expr
->ts
.type
== BT_DERIVED
8429 && expr
->ts
.is_iso_c
&& expr
->ts
.u
.derived
)
8431 if (TREE_CODE (type
) == ARRAY_TYPE
)
8432 return build_constructor (type
, NULL
);
8433 else if (POINTER_TYPE_P (type
))
8434 return build_int_cst (type
, 0);
8439 if (array
&& !procptr
)
8442 /* Arrays need special handling. */
8444 ctor
= gfc_build_null_descriptor (type
);
8445 /* Special case assigning an array to zero. */
8446 else if (is_zero_initializer_p (expr
))
8447 ctor
= build_constructor (type
, NULL
);
8449 ctor
= gfc_conv_array_initializer (type
, expr
);
8450 TREE_STATIC (ctor
) = 1;
8453 else if (pointer
|| procptr
)
8455 if (ts
->type
== BT_CLASS
&& !procptr
)
8457 gfc_init_se (&se
, NULL
);
8458 gfc_conv_structure (&se
, gfc_class_initializer (ts
, expr
), 1);
8459 gcc_assert (TREE_CODE (se
.expr
) == CONSTRUCTOR
);
8460 TREE_STATIC (se
.expr
) = 1;
8463 else if (!expr
|| expr
->expr_type
== EXPR_NULL
)
8464 return fold_convert (type
, null_pointer_node
);
8467 gfc_init_se (&se
, NULL
);
8468 se
.want_pointer
= 1;
8469 gfc_conv_expr (&se
, expr
);
8470 gcc_assert (TREE_CODE (se
.expr
) != CONSTRUCTOR
);
8480 gfc_init_se (&se
, NULL
);
8481 if (ts
->type
== BT_CLASS
&& expr
->expr_type
== EXPR_NULL
)
8482 gfc_conv_structure (&se
, gfc_class_initializer (ts
, expr
), 1);
8484 gfc_conv_structure (&se
, expr
, 1);
8485 gcc_assert (TREE_CODE (se
.expr
) == CONSTRUCTOR
);
8486 TREE_STATIC (se
.expr
) = 1;
8490 if (expr
->expr_type
== EXPR_CONSTANT
)
8492 tree ctor
= gfc_conv_string_init (ts
->u
.cl
->backend_decl
, expr
);
8493 TREE_STATIC (ctor
) = 1;
8499 gfc_init_se (&se
, NULL
);
8500 gfc_conv_constant (&se
, expr
);
8501 gcc_assert (TREE_CODE (se
.expr
) != CONSTRUCTOR
);
8508 gfc_trans_subarray_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
)
8514 gfc_array_info
*lss_array
;
8521 gfc_start_block (&block
);
8523 /* Initialize the scalarizer. */
8524 gfc_init_loopinfo (&loop
);
8526 gfc_init_se (&lse
, NULL
);
8527 gfc_init_se (&rse
, NULL
);
8530 rss
= gfc_walk_expr (expr
);
8531 if (rss
== gfc_ss_terminator
)
8532 /* The rhs is scalar. Add a ss for the expression. */
8533 rss
= gfc_get_scalar_ss (gfc_ss_terminator
, expr
);
8535 /* Create a SS for the destination. */
8536 lss
= gfc_get_array_ss (gfc_ss_terminator
, NULL
, cm
->as
->rank
,
8538 lss_array
= &lss
->info
->data
.array
;
8539 lss_array
->shape
= gfc_get_shape (cm
->as
->rank
);
8540 lss_array
->descriptor
= dest
;
8541 lss_array
->data
= gfc_conv_array_data (dest
);
8542 lss_array
->offset
= gfc_conv_array_offset (dest
);
8543 for (n
= 0; n
< cm
->as
->rank
; n
++)
8545 lss_array
->start
[n
] = gfc_conv_array_lbound (dest
, n
);
8546 lss_array
->stride
[n
] = gfc_index_one_node
;
8548 mpz_init (lss_array
->shape
[n
]);
8549 mpz_sub (lss_array
->shape
[n
], cm
->as
->upper
[n
]->value
.integer
,
8550 cm
->as
->lower
[n
]->value
.integer
);
8551 mpz_add_ui (lss_array
->shape
[n
], lss_array
->shape
[n
], 1);
8554 /* Associate the SS with the loop. */
8555 gfc_add_ss_to_loop (&loop
, lss
);
8556 gfc_add_ss_to_loop (&loop
, rss
);
8558 /* Calculate the bounds of the scalarization. */
8559 gfc_conv_ss_startstride (&loop
);
8561 /* Setup the scalarizing loops. */
8562 gfc_conv_loop_setup (&loop
, &expr
->where
);
8564 /* Setup the gfc_se structures. */
8565 gfc_copy_loopinfo_to_se (&lse
, &loop
);
8566 gfc_copy_loopinfo_to_se (&rse
, &loop
);
8569 gfc_mark_ss_chain_used (rss
, 1);
8571 gfc_mark_ss_chain_used (lss
, 1);
8573 /* Start the scalarized loop body. */
8574 gfc_start_scalarized_body (&loop
, &body
);
8576 gfc_conv_tmp_array_ref (&lse
);
8577 if (cm
->ts
.type
== BT_CHARACTER
)
8578 lse
.string_length
= cm
->ts
.u
.cl
->backend_decl
;
8580 gfc_conv_expr (&rse
, expr
);
8582 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, cm
->ts
, true, false);
8583 gfc_add_expr_to_block (&body
, tmp
);
8585 gcc_assert (rse
.ss
== gfc_ss_terminator
);
8587 /* Generate the copying loops. */
8588 gfc_trans_scalarizing_loops (&loop
, &body
);
8590 /* Wrap the whole thing up. */
8591 gfc_add_block_to_block (&block
, &loop
.pre
);
8592 gfc_add_block_to_block (&block
, &loop
.post
);
8594 gcc_assert (lss_array
->shape
!= NULL
);
8595 gfc_free_shape (&lss_array
->shape
, cm
->as
->rank
);
8596 gfc_cleanup_loop (&loop
);
8598 return gfc_finish_block (&block
);
8603 gfc_trans_alloc_subarray_assign (tree dest
, gfc_component
* cm
,
8613 gfc_expr
*arg
= NULL
;
8615 gfc_start_block (&block
);
8616 gfc_init_se (&se
, NULL
);
8618 /* Get the descriptor for the expressions. */
8619 se
.want_pointer
= 0;
8620 gfc_conv_expr_descriptor (&se
, expr
);
8621 gfc_add_block_to_block (&block
, &se
.pre
);
8622 gfc_add_modify (&block
, dest
, se
.expr
);
8624 /* Deal with arrays of derived types with allocatable components. */
8625 if (gfc_bt_struct (cm
->ts
.type
)
8626 && cm
->ts
.u
.derived
->attr
.alloc_comp
)
8627 // TODO: Fix caf_mode
8628 tmp
= gfc_copy_alloc_comp (cm
->ts
.u
.derived
,
8631 else if (cm
->ts
.type
== BT_CLASS
&& expr
->ts
.type
== BT_DERIVED
8632 && CLASS_DATA(cm
)->attr
.allocatable
)
8634 if (cm
->ts
.u
.derived
->attr
.alloc_comp
)
8635 // TODO: Fix caf_mode
8636 tmp
= gfc_copy_alloc_comp (expr
->ts
.u
.derived
,
8641 tmp
= TREE_TYPE (dest
);
8642 tmp
= gfc_duplicate_allocatable (dest
, se
.expr
,
8643 tmp
, expr
->rank
, NULL_TREE
);
8647 tmp
= gfc_duplicate_allocatable (dest
, se
.expr
,
8648 TREE_TYPE(cm
->backend_decl
),
8649 cm
->as
->rank
, NULL_TREE
);
8651 gfc_add_expr_to_block (&block
, tmp
);
8652 gfc_add_block_to_block (&block
, &se
.post
);
8654 if (expr
->expr_type
!= EXPR_VARIABLE
)
8655 gfc_conv_descriptor_data_set (&block
, se
.expr
,
8658 /* We need to know if the argument of a conversion function is a
8659 variable, so that the correct lower bound can be used. */
8660 if (expr
->expr_type
== EXPR_FUNCTION
8661 && expr
->value
.function
.isym
8662 && expr
->value
.function
.isym
->conversion
8663 && expr
->value
.function
.actual
->expr
8664 && expr
->value
.function
.actual
->expr
->expr_type
== EXPR_VARIABLE
)
8665 arg
= expr
->value
.function
.actual
->expr
;
8667 /* Obtain the array spec of full array references. */
8669 as
= gfc_get_full_arrayspec_from_expr (arg
);
8671 as
= gfc_get_full_arrayspec_from_expr (expr
);
8673 /* Shift the lbound and ubound of temporaries to being unity,
8674 rather than zero, based. Always calculate the offset. */
8675 offset
= gfc_conv_descriptor_offset_get (dest
);
8676 gfc_add_modify (&block
, offset
, gfc_index_zero_node
);
8677 tmp2
=gfc_create_var (gfc_array_index_type
, NULL
);
8679 for (n
= 0; n
< expr
->rank
; n
++)
8684 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8685 TODO It looks as if gfc_conv_expr_descriptor should return
8686 the correct bounds and that the following should not be
8687 necessary. This would simplify gfc_conv_intrinsic_bound
8689 if (as
&& as
->lower
[n
])
8692 gfc_init_se (&lbse
, NULL
);
8693 gfc_conv_expr (&lbse
, as
->lower
[n
]);
8694 gfc_add_block_to_block (&block
, &lbse
.pre
);
8695 lbound
= gfc_evaluate_now (lbse
.expr
, &block
);
8699 tmp
= gfc_get_symbol_decl (arg
->symtree
->n
.sym
);
8700 lbound
= gfc_conv_descriptor_lbound_get (tmp
,
8704 lbound
= gfc_conv_descriptor_lbound_get (dest
,
8707 lbound
= gfc_index_one_node
;
8709 lbound
= fold_convert (gfc_array_index_type
, lbound
);
8711 /* Shift the bounds and set the offset accordingly. */
8712 tmp
= gfc_conv_descriptor_ubound_get (dest
, gfc_rank_cst
[n
]);
8713 span
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
8714 tmp
, gfc_conv_descriptor_lbound_get (dest
, gfc_rank_cst
[n
]));
8715 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
8717 gfc_conv_descriptor_ubound_set (&block
, dest
,
8718 gfc_rank_cst
[n
], tmp
);
8719 gfc_conv_descriptor_lbound_set (&block
, dest
,
8720 gfc_rank_cst
[n
], lbound
);
8722 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
8723 gfc_conv_descriptor_lbound_get (dest
,
8725 gfc_conv_descriptor_stride_get (dest
,
8727 gfc_add_modify (&block
, tmp2
, tmp
);
8728 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
8730 gfc_conv_descriptor_offset_set (&block
, dest
, tmp
);
8735 /* If a conversion expression has a null data pointer
8736 argument, nullify the allocatable component. */
8740 if (arg
->symtree
->n
.sym
->attr
.allocatable
8741 || arg
->symtree
->n
.sym
->attr
.pointer
)
8743 non_null_expr
= gfc_finish_block (&block
);
8744 gfc_start_block (&block
);
8745 gfc_conv_descriptor_data_set (&block
, dest
,
8747 null_expr
= gfc_finish_block (&block
);
8748 tmp
= gfc_conv_descriptor_data_get (arg
->symtree
->n
.sym
->backend_decl
);
8749 tmp
= build2_loc (input_location
, EQ_EXPR
, logical_type_node
, tmp
,
8750 fold_convert (TREE_TYPE (tmp
), null_pointer_node
));
8751 return build3_v (COND_EXPR
, tmp
,
8752 null_expr
, non_null_expr
);
8756 return gfc_finish_block (&block
);
8760 /* Allocate or reallocate scalar component, as necessary. */
8763 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t
*block
,
8773 tree lhs_cl_size
= NULL_TREE
;
8778 if (!expr2
|| expr2
->rank
)
8781 realloc_lhs_warning (expr2
->ts
.type
, false, &expr2
->where
);
8783 if (cm
->ts
.type
== BT_CHARACTER
&& cm
->ts
.deferred
)
8785 char name
[GFC_MAX_SYMBOL_LEN
+9];
8786 gfc_component
*strlen
;
8787 /* Use the rhs string length and the lhs element size. */
8788 gcc_assert (expr2
->ts
.type
== BT_CHARACTER
);
8789 if (!expr2
->ts
.u
.cl
->backend_decl
)
8791 gfc_conv_string_length (expr2
->ts
.u
.cl
, expr2
, block
);
8792 gcc_assert (expr2
->ts
.u
.cl
->backend_decl
);
8795 size
= expr2
->ts
.u
.cl
->backend_decl
;
8797 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8799 sprintf (name
, "_%s_length", cm
->name
);
8800 strlen
= gfc_find_component (sym
, name
, true, true, NULL
);
8801 lhs_cl_size
= fold_build3_loc (input_location
, COMPONENT_REF
,
8802 gfc_charlen_type_node
,
8803 TREE_OPERAND (comp
, 0),
8804 strlen
->backend_decl
, NULL_TREE
);
8806 tmp
= TREE_TYPE (gfc_typenode_for_spec (&cm
->ts
));
8807 tmp
= TYPE_SIZE_UNIT (tmp
);
8808 size_in_bytes
= fold_build2_loc (input_location
, MULT_EXPR
,
8809 TREE_TYPE (tmp
), tmp
,
8810 fold_convert (TREE_TYPE (tmp
), size
));
8812 else if (cm
->ts
.type
== BT_CLASS
)
8814 gcc_assert (expr2
->ts
.type
== BT_CLASS
|| expr2
->ts
.type
== BT_DERIVED
);
8815 if (expr2
->ts
.type
== BT_DERIVED
)
8817 tmp
= gfc_get_symbol_decl (expr2
->ts
.u
.derived
);
8818 size
= TYPE_SIZE_UNIT (tmp
);
8824 e2vtab
= gfc_find_and_cut_at_last_class_ref (expr2
);
8825 gfc_add_vptr_component (e2vtab
);
8826 gfc_add_size_component (e2vtab
);
8827 gfc_init_se (&se
, NULL
);
8828 gfc_conv_expr (&se
, e2vtab
);
8829 gfc_add_block_to_block (block
, &se
.pre
);
8830 size
= fold_convert (size_type_node
, se
.expr
);
8831 gfc_free_expr (e2vtab
);
8833 size_in_bytes
= size
;
8837 /* Otherwise use the length in bytes of the rhs. */
8838 size
= TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm
->ts
));
8839 size_in_bytes
= size
;
8842 size_in_bytes
= fold_build2_loc (input_location
, MAX_EXPR
, size_type_node
,
8843 size_in_bytes
, size_one_node
);
8845 if (cm
->ts
.type
== BT_DERIVED
&& cm
->ts
.u
.derived
->attr
.alloc_comp
)
8847 tmp
= build_call_expr_loc (input_location
,
8848 builtin_decl_explicit (BUILT_IN_CALLOC
),
8849 2, build_one_cst (size_type_node
),
8851 tmp
= fold_convert (TREE_TYPE (comp
), tmp
);
8852 gfc_add_modify (block
, comp
, tmp
);
8856 tmp
= build_call_expr_loc (input_location
,
8857 builtin_decl_explicit (BUILT_IN_MALLOC
),
8859 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp
)))
8860 ptr
= gfc_class_data_get (comp
);
8863 tmp
= fold_convert (TREE_TYPE (ptr
), tmp
);
8864 gfc_add_modify (block
, ptr
, tmp
);
8867 if (cm
->ts
.type
== BT_CHARACTER
&& cm
->ts
.deferred
)
8868 /* Update the lhs character length. */
8869 gfc_add_modify (block
, lhs_cl_size
,
8870 fold_convert (TREE_TYPE (lhs_cl_size
), size
));
8874 /* Assign a single component of a derived type constructor. */
8877 gfc_trans_subcomponent_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
,
8878 gfc_symbol
*sym
, bool init
)
8886 gfc_start_block (&block
);
8888 if (cm
->attr
.pointer
|| cm
->attr
.proc_pointer
)
8890 /* Only care about pointers here, not about allocatables. */
8891 gfc_init_se (&se
, NULL
);
8892 /* Pointer component. */
8893 if ((cm
->attr
.dimension
|| cm
->attr
.codimension
)
8894 && !cm
->attr
.proc_pointer
)
8896 /* Array pointer. */
8897 if (expr
->expr_type
== EXPR_NULL
)
8898 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
8901 se
.direct_byref
= 1;
8903 gfc_conv_expr_descriptor (&se
, expr
);
8904 gfc_add_block_to_block (&block
, &se
.pre
);
8905 gfc_add_block_to_block (&block
, &se
.post
);
8910 /* Scalar pointers. */
8911 se
.want_pointer
= 1;
8912 gfc_conv_expr (&se
, expr
);
8913 gfc_add_block_to_block (&block
, &se
.pre
);
8915 if (expr
->symtree
&& expr
->symtree
->n
.sym
->attr
.proc_pointer
8916 && expr
->symtree
->n
.sym
->attr
.dummy
)
8917 se
.expr
= build_fold_indirect_ref_loc (input_location
, se
.expr
);
8919 gfc_add_modify (&block
, dest
,
8920 fold_convert (TREE_TYPE (dest
), se
.expr
));
8921 gfc_add_block_to_block (&block
, &se
.post
);
8924 else if (cm
->ts
.type
== BT_CLASS
&& expr
->expr_type
== EXPR_NULL
)
8926 /* NULL initialization for CLASS components. */
8927 tmp
= gfc_trans_structure_assign (dest
,
8928 gfc_class_initializer (&cm
->ts
, expr
),
8930 gfc_add_expr_to_block (&block
, tmp
);
8932 else if ((cm
->attr
.dimension
|| cm
->attr
.codimension
)
8933 && !cm
->attr
.proc_pointer
)
8935 if (cm
->attr
.allocatable
&& expr
->expr_type
== EXPR_NULL
)
8936 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
8937 else if (cm
->attr
.allocatable
|| cm
->attr
.pdt_array
)
8939 tmp
= gfc_trans_alloc_subarray_assign (dest
, cm
, expr
);
8940 gfc_add_expr_to_block (&block
, tmp
);
8944 tmp
= gfc_trans_subarray_assign (dest
, cm
, expr
);
8945 gfc_add_expr_to_block (&block
, tmp
);
8948 else if (cm
->ts
.type
== BT_CLASS
8949 && CLASS_DATA (cm
)->attr
.dimension
8950 && CLASS_DATA (cm
)->attr
.allocatable
8951 && expr
->ts
.type
== BT_DERIVED
)
8953 vtab
= gfc_get_symbol_decl (gfc_find_vtab (&expr
->ts
));
8954 vtab
= gfc_build_addr_expr (NULL_TREE
, vtab
);
8955 tmp
= gfc_class_vptr_get (dest
);
8956 gfc_add_modify (&block
, tmp
,
8957 fold_convert (TREE_TYPE (tmp
), vtab
));
8958 tmp
= gfc_class_data_get (dest
);
8959 tmp
= gfc_trans_alloc_subarray_assign (tmp
, cm
, expr
);
8960 gfc_add_expr_to_block (&block
, tmp
);
8962 else if (init
&& cm
->attr
.allocatable
&& expr
->expr_type
== EXPR_NULL
)
8964 /* NULL initialization for allocatable components. */
8965 gfc_add_modify (&block
, dest
, fold_convert (TREE_TYPE (dest
),
8966 null_pointer_node
));
8968 else if (init
&& (cm
->attr
.allocatable
8969 || (cm
->ts
.type
== BT_CLASS
&& CLASS_DATA (cm
)->attr
.allocatable
8970 && expr
->ts
.type
!= BT_CLASS
)))
8972 /* Take care about non-array allocatable components here. The alloc_*
8973 routine below is motivated by the alloc_scalar_allocatable_for_
8974 assignment() routine, but with the realloc portions removed and
8976 alloc_scalar_allocatable_for_subcomponent_assignment (&block
,
8981 /* The remainder of these instructions follow the if (cm->attr.pointer)
8982 if (!cm->attr.dimension) part above. */
8983 gfc_init_se (&se
, NULL
);
8984 gfc_conv_expr (&se
, expr
);
8985 gfc_add_block_to_block (&block
, &se
.pre
);
8987 if (expr
->symtree
&& expr
->symtree
->n
.sym
->attr
.proc_pointer
8988 && expr
->symtree
->n
.sym
->attr
.dummy
)
8989 se
.expr
= build_fold_indirect_ref_loc (input_location
, se
.expr
);
8991 if (cm
->ts
.type
== BT_CLASS
&& expr
->ts
.type
== BT_DERIVED
)
8993 tmp
= gfc_class_data_get (dest
);
8994 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
8995 vtab
= gfc_get_symbol_decl (gfc_find_vtab (&expr
->ts
));
8996 vtab
= gfc_build_addr_expr (NULL_TREE
, vtab
);
8997 gfc_add_modify (&block
, gfc_class_vptr_get (dest
),
8998 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest
)), vtab
));
9001 tmp
= build_fold_indirect_ref_loc (input_location
, dest
);
9003 /* For deferred strings insert a memcpy. */
9004 if (cm
->ts
.type
== BT_CHARACTER
&& cm
->ts
.deferred
)
9007 gcc_assert (se
.string_length
|| expr
->ts
.u
.cl
->backend_decl
);
9008 size
= size_of_string_in_bytes (cm
->ts
.kind
, se
.string_length
9010 : expr
->ts
.u
.cl
->backend_decl
);
9011 tmp
= gfc_build_memcpy_call (tmp
, se
.expr
, size
);
9012 gfc_add_expr_to_block (&block
, tmp
);
9015 gfc_add_modify (&block
, tmp
,
9016 fold_convert (TREE_TYPE (tmp
), se
.expr
));
9017 gfc_add_block_to_block (&block
, &se
.post
);
9019 else if (expr
->ts
.type
== BT_UNION
)
9022 gfc_constructor
*c
= gfc_constructor_first (expr
->value
.constructor
);
9023 /* We mark that the entire union should be initialized with a contrived
9024 EXPR_NULL expression at the beginning. */
9025 if (c
!= NULL
&& c
->n
.component
== NULL
9026 && c
->expr
!= NULL
&& c
->expr
->expr_type
== EXPR_NULL
)
9028 tmp
= build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
9029 dest
, build_constructor (TREE_TYPE (dest
), NULL
));
9030 gfc_add_expr_to_block (&block
, tmp
);
9031 c
= gfc_constructor_next (c
);
9033 /* The following constructor expression, if any, represents a specific
9034 map intializer, as given by the user. */
9035 if (c
!= NULL
&& c
->expr
!= NULL
)
9037 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
9038 tmp
= gfc_trans_structure_assign (dest
, expr
, expr
->symtree
!= NULL
);
9039 gfc_add_expr_to_block (&block
, tmp
);
9042 else if (expr
->ts
.type
== BT_DERIVED
&& expr
->ts
.f90_type
!= BT_VOID
)
9044 if (expr
->expr_type
!= EXPR_STRUCTURE
)
9046 tree dealloc
= NULL_TREE
;
9047 gfc_init_se (&se
, NULL
);
9048 gfc_conv_expr (&se
, expr
);
9049 gfc_add_block_to_block (&block
, &se
.pre
);
9050 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
9051 expression in a temporary variable and deallocate the allocatable
9052 components. Then we can the copy the expression to the result. */
9053 if (cm
->ts
.u
.derived
->attr
.alloc_comp
9054 && expr
->expr_type
!= EXPR_VARIABLE
)
9056 se
.expr
= gfc_evaluate_now (se
.expr
, &block
);
9057 dealloc
= gfc_deallocate_alloc_comp (cm
->ts
.u
.derived
, se
.expr
,
9060 gfc_add_modify (&block
, dest
,
9061 fold_convert (TREE_TYPE (dest
), se
.expr
));
9062 if (cm
->ts
.u
.derived
->attr
.alloc_comp
9063 && expr
->expr_type
!= EXPR_NULL
)
9065 // TODO: Fix caf_mode
9066 tmp
= gfc_copy_alloc_comp (cm
->ts
.u
.derived
, se
.expr
,
9067 dest
, expr
->rank
, 0);
9068 gfc_add_expr_to_block (&block
, tmp
);
9069 if (dealloc
!= NULL_TREE
)
9070 gfc_add_expr_to_block (&block
, dealloc
);
9072 gfc_add_block_to_block (&block
, &se
.post
);
9076 /* Nested constructors. */
9077 tmp
= gfc_trans_structure_assign (dest
, expr
, expr
->symtree
!= NULL
);
9078 gfc_add_expr_to_block (&block
, tmp
);
9081 else if (gfc_deferred_strlen (cm
, &tmp
))
9085 gcc_assert (strlen
);
9086 strlen
= fold_build3_loc (input_location
, COMPONENT_REF
,
9088 TREE_OPERAND (dest
, 0),
9091 if (expr
->expr_type
== EXPR_NULL
)
9093 tmp
= build_int_cst (TREE_TYPE (cm
->backend_decl
), 0);
9094 gfc_add_modify (&block
, dest
, tmp
);
9095 tmp
= build_int_cst (TREE_TYPE (strlen
), 0);
9096 gfc_add_modify (&block
, strlen
, tmp
);
9101 gfc_init_se (&se
, NULL
);
9102 gfc_conv_expr (&se
, expr
);
9103 size
= size_of_string_in_bytes (cm
->ts
.kind
, se
.string_length
);
9104 tmp
= build_call_expr_loc (input_location
,
9105 builtin_decl_explicit (BUILT_IN_MALLOC
),
9107 gfc_add_modify (&block
, dest
,
9108 fold_convert (TREE_TYPE (dest
), tmp
));
9109 gfc_add_modify (&block
, strlen
,
9110 fold_convert (TREE_TYPE (strlen
), se
.string_length
));
9111 tmp
= gfc_build_memcpy_call (dest
, se
.expr
, size
);
9112 gfc_add_expr_to_block (&block
, tmp
);
9115 else if (!cm
->attr
.artificial
)
9117 /* Scalar component (excluding deferred parameters). */
9118 gfc_init_se (&se
, NULL
);
9119 gfc_init_se (&lse
, NULL
);
9121 gfc_conv_expr (&se
, expr
);
9122 if (cm
->ts
.type
== BT_CHARACTER
)
9123 lse
.string_length
= cm
->ts
.u
.cl
->backend_decl
;
9125 tmp
= gfc_trans_scalar_assign (&lse
, &se
, cm
->ts
, false, false);
9126 gfc_add_expr_to_block (&block
, tmp
);
9128 return gfc_finish_block (&block
);
9131 /* Assign a derived type constructor to a variable. */
9134 gfc_trans_structure_assign (tree dest
, gfc_expr
* expr
, bool init
, bool coarray
)
9143 gfc_start_block (&block
);
9145 if (expr
->ts
.u
.derived
->from_intmod
== INTMOD_ISO_C_BINDING
9146 && (expr
->ts
.u
.derived
->intmod_sym_id
== ISOCBINDING_PTR
9147 || expr
->ts
.u
.derived
->intmod_sym_id
== ISOCBINDING_FUNPTR
))
9151 gfc_init_se (&se
, NULL
);
9152 gfc_init_se (&lse
, NULL
);
9153 gfc_conv_expr (&se
, gfc_constructor_first (expr
->value
.constructor
)->expr
);
9155 gfc_add_modify (&block
, lse
.expr
,
9156 fold_convert (TREE_TYPE (lse
.expr
), se
.expr
));
9158 return gfc_finish_block (&block
);
9161 /* Make sure that the derived type has been completely built. */
9162 if (!expr
->ts
.u
.derived
->backend_decl
9163 || !TYPE_FIELDS (expr
->ts
.u
.derived
->backend_decl
))
9165 tmp
= gfc_typenode_for_spec (&expr
->ts
);
9169 cm
= expr
->ts
.u
.derived
->components
;
9173 gfc_init_se (&se
, NULL
);
9175 for (c
= gfc_constructor_first (expr
->value
.constructor
);
9176 c
; c
= gfc_constructor_next (c
), cm
= cm
->next
)
9178 /* Skip absent members in default initializers. */
9179 if (!c
->expr
&& !cm
->attr
.allocatable
)
9182 /* Register the component with the caf-lib before it is initialized.
9183 Register only allocatable components, that are not coarray'ed
9184 components (%comp[*]). Only register when the constructor is not the
9186 if (coarray
&& !cm
->attr
.codimension
9187 && (cm
->attr
.allocatable
|| cm
->attr
.pointer
)
9188 && (!c
->expr
|| c
->expr
->expr_type
== EXPR_NULL
))
9190 tree token
, desc
, size
;
9191 bool is_array
= cm
->ts
.type
== BT_CLASS
9192 ? CLASS_DATA (cm
)->attr
.dimension
: cm
->attr
.dimension
;
9194 field
= cm
->backend_decl
;
9195 field
= fold_build3_loc (input_location
, COMPONENT_REF
,
9196 TREE_TYPE (field
), dest
, field
, NULL_TREE
);
9197 if (cm
->ts
.type
== BT_CLASS
)
9198 field
= gfc_class_data_get (field
);
9200 token
= is_array
? gfc_conv_descriptor_token (field
)
9201 : fold_build3_loc (input_location
, COMPONENT_REF
,
9202 TREE_TYPE (cm
->caf_token
), dest
,
9203 cm
->caf_token
, NULL_TREE
);
9207 /* The _caf_register routine looks at the rank of the array
9208 descriptor to decide whether the data registered is an array
9210 int rank
= cm
->ts
.type
== BT_CLASS
? CLASS_DATA (cm
)->as
->rank
9212 /* When the rank is not known just set a positive rank, which
9213 suffices to recognize the data as array. */
9216 size
= build_zero_cst (size_type_node
);
9218 gfc_add_modify (&block
, gfc_conv_descriptor_rank (desc
),
9219 build_int_cst (signed_char_type_node
, rank
));
9223 desc
= gfc_conv_scalar_to_descriptor (&se
, field
,
9224 cm
->ts
.type
== BT_CLASS
9225 ? CLASS_DATA (cm
)->attr
9227 size
= TYPE_SIZE_UNIT (TREE_TYPE (field
));
9229 gfc_add_block_to_block (&block
, &se
.pre
);
9230 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_register
,
9231 7, size
, build_int_cst (
9233 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY
),
9234 gfc_build_addr_expr (pvoid_type_node
,
9236 gfc_build_addr_expr (NULL_TREE
, desc
),
9237 null_pointer_node
, null_pointer_node
,
9239 gfc_add_expr_to_block (&block
, tmp
);
9241 field
= cm
->backend_decl
;
9243 tmp
= fold_build3_loc (input_location
, COMPONENT_REF
, TREE_TYPE (field
),
9244 dest
, field
, NULL_TREE
);
9247 gfc_expr
*e
= gfc_get_null_expr (NULL
);
9248 tmp
= gfc_trans_subcomponent_assign (tmp
, cm
, e
, expr
->ts
.u
.derived
,
9253 tmp
= gfc_trans_subcomponent_assign (tmp
, cm
, c
->expr
,
9254 expr
->ts
.u
.derived
, init
);
9255 gfc_add_expr_to_block (&block
, tmp
);
9257 return gfc_finish_block (&block
);
9261 gfc_conv_union_initializer (vec
<constructor_elt
, va_gc
> *&v
,
9262 gfc_component
*un
, gfc_expr
*init
)
9264 gfc_constructor
*ctor
;
9266 if (un
->ts
.type
!= BT_UNION
|| un
== NULL
|| init
== NULL
)
9269 ctor
= gfc_constructor_first (init
->value
.constructor
);
9271 if (ctor
== NULL
|| ctor
->expr
== NULL
)
9274 gcc_assert (init
->expr_type
== EXPR_STRUCTURE
);
9276 /* If we have an 'initialize all' constructor, do it first. */
9277 if (ctor
->expr
->expr_type
== EXPR_NULL
)
9279 tree union_type
= TREE_TYPE (un
->backend_decl
);
9280 tree val
= build_constructor (union_type
, NULL
);
9281 CONSTRUCTOR_APPEND_ELT (v
, un
->backend_decl
, val
);
9282 ctor
= gfc_constructor_next (ctor
);
9285 /* Add the map initializer on top. */
9286 if (ctor
!= NULL
&& ctor
->expr
!= NULL
)
9288 gcc_assert (ctor
->expr
->expr_type
== EXPR_STRUCTURE
);
9289 tree val
= gfc_conv_initializer (ctor
->expr
, &un
->ts
,
9290 TREE_TYPE (un
->backend_decl
),
9291 un
->attr
.dimension
, un
->attr
.pointer
,
9292 un
->attr
.proc_pointer
);
9293 CONSTRUCTOR_APPEND_ELT (v
, un
->backend_decl
, val
);
9297 /* Build an expression for a constructor. If init is nonzero then
9298 this is part of a static variable initializer. */
9301 gfc_conv_structure (gfc_se
* se
, gfc_expr
* expr
, int init
)
9308 vec
<constructor_elt
, va_gc
> *v
= NULL
;
9310 gcc_assert (se
->ss
== NULL
);
9311 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
9312 type
= gfc_typenode_for_spec (&expr
->ts
);
9316 /* Create a temporary variable and fill it in. */
9317 se
->expr
= gfc_create_var (type
, expr
->ts
.u
.derived
->name
);
9318 /* The symtree in expr is NULL, if the code to generate is for
9319 initializing the static members only. */
9320 tmp
= gfc_trans_structure_assign (se
->expr
, expr
, expr
->symtree
!= NULL
,
9322 gfc_add_expr_to_block (&se
->pre
, tmp
);
9326 cm
= expr
->ts
.u
.derived
->components
;
9328 for (c
= gfc_constructor_first (expr
->value
.constructor
);
9329 c
; c
= gfc_constructor_next (c
), cm
= cm
->next
)
9331 /* Skip absent members in default initializers and allocatable
9332 components. Although the latter have a default initializer
9333 of EXPR_NULL,... by default, the static nullify is not needed
9334 since this is done every time we come into scope. */
9335 if (!c
->expr
|| (cm
->attr
.allocatable
&& cm
->attr
.flavor
!= FL_PROCEDURE
))
9338 if (cm
->initializer
&& cm
->initializer
->expr_type
!= EXPR_NULL
9339 && strcmp (cm
->name
, "_extends") == 0
9340 && cm
->initializer
->symtree
)
9344 vtabs
= cm
->initializer
->symtree
->n
.sym
;
9345 vtab
= gfc_build_addr_expr (NULL_TREE
, gfc_get_symbol_decl (vtabs
));
9346 vtab
= unshare_expr_without_location (vtab
);
9347 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
, vtab
);
9349 else if (cm
->ts
.u
.derived
&& strcmp (cm
->name
, "_size") == 0)
9351 val
= TYPE_SIZE_UNIT (gfc_get_derived_type (cm
->ts
.u
.derived
));
9352 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
,
9353 fold_convert (TREE_TYPE (cm
->backend_decl
),
9356 else if (cm
->ts
.type
== BT_INTEGER
&& strcmp (cm
->name
, "_len") == 0)
9357 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
,
9358 fold_convert (TREE_TYPE (cm
->backend_decl
),
9359 integer_zero_node
));
9360 else if (cm
->ts
.type
== BT_UNION
)
9361 gfc_conv_union_initializer (v
, cm
, c
->expr
);
9364 val
= gfc_conv_initializer (c
->expr
, &cm
->ts
,
9365 TREE_TYPE (cm
->backend_decl
),
9366 cm
->attr
.dimension
, cm
->attr
.pointer
,
9367 cm
->attr
.proc_pointer
);
9368 val
= unshare_expr_without_location (val
);
9370 /* Append it to the constructor list. */
9371 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
, val
);
9375 se
->expr
= build_constructor (type
, v
);
9377 TREE_CONSTANT (se
->expr
) = 1;
9381 /* Translate a substring expression. */
9384 gfc_conv_substring_expr (gfc_se
* se
, gfc_expr
* expr
)
9390 gcc_assert (ref
== NULL
|| ref
->type
== REF_SUBSTRING
);
9392 se
->expr
= gfc_build_wide_string_const (expr
->ts
.kind
,
9393 expr
->value
.character
.length
,
9394 expr
->value
.character
.string
);
9396 se
->string_length
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se
->expr
)));
9397 TYPE_STRING_FLAG (TREE_TYPE (se
->expr
)) = 1;
9400 gfc_conv_substring (se
, ref
, expr
->ts
.kind
, NULL
, &expr
->where
);
9404 /* Entry point for expression translation. Evaluates a scalar quantity.
9405 EXPR is the expression to be translated, and SE is the state structure if
9406 called from within the scalarized. */
9409 gfc_conv_expr (gfc_se
* se
, gfc_expr
* expr
)
9414 if (ss
&& ss
->info
->expr
== expr
9415 && (ss
->info
->type
== GFC_SS_SCALAR
9416 || ss
->info
->type
== GFC_SS_REFERENCE
))
9418 gfc_ss_info
*ss_info
;
9421 /* Substitute a scalar expression evaluated outside the scalarization
9423 se
->expr
= ss_info
->data
.scalar
.value
;
9424 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info
))
9425 se
->expr
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
9427 se
->string_length
= ss_info
->string_length
;
9428 gfc_advance_se_ss_chain (se
);
9432 /* We need to convert the expressions for the iso_c_binding derived types.
9433 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
9434 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
9435 typespec for the C_PTR and C_FUNPTR symbols, which has already been
9436 updated to be an integer with a kind equal to the size of a (void *). */
9437 if (expr
->ts
.type
== BT_DERIVED
&& expr
->ts
.u
.derived
->ts
.f90_type
== BT_VOID
9438 && expr
->ts
.u
.derived
->attr
.is_bind_c
)
9440 if (expr
->expr_type
== EXPR_VARIABLE
9441 && (expr
->symtree
->n
.sym
->intmod_sym_id
== ISOCBINDING_NULL_PTR
9442 || expr
->symtree
->n
.sym
->intmod_sym_id
9443 == ISOCBINDING_NULL_FUNPTR
))
9445 /* Set expr_type to EXPR_NULL, which will result in
9446 null_pointer_node being used below. */
9447 expr
->expr_type
= EXPR_NULL
;
9451 /* Update the type/kind of the expression to be what the new
9452 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
9453 expr
->ts
.type
= BT_INTEGER
;
9454 expr
->ts
.f90_type
= BT_VOID
;
9455 expr
->ts
.kind
= gfc_index_integer_kind
;
9459 gfc_fix_class_refs (expr
);
9461 switch (expr
->expr_type
)
9464 gfc_conv_expr_op (se
, expr
);
9468 gfc_conv_function_expr (se
, expr
);
9472 gfc_conv_constant (se
, expr
);
9476 gfc_conv_variable (se
, expr
);
9480 se
->expr
= null_pointer_node
;
9483 case EXPR_SUBSTRING
:
9484 gfc_conv_substring_expr (se
, expr
);
9487 case EXPR_STRUCTURE
:
9488 gfc_conv_structure (se
, expr
, 0);
9492 gfc_conv_array_constructor_expr (se
, expr
);
9501 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9502 of an assignment. */
9504 gfc_conv_expr_lhs (gfc_se
* se
, gfc_expr
* expr
)
9506 gfc_conv_expr (se
, expr
);
9507 /* All numeric lvalues should have empty post chains. If not we need to
9508 figure out a way of rewriting an lvalue so that it has no post chain. */
9509 gcc_assert (expr
->ts
.type
== BT_CHARACTER
|| !se
->post
.head
);
9512 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9513 numeric expressions. Used for scalar values where inserting cleanup code
9516 gfc_conv_expr_val (gfc_se
* se
, gfc_expr
* expr
)
9520 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
9521 gfc_conv_expr (se
, expr
);
9524 val
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
9525 gfc_add_modify (&se
->pre
, val
, se
->expr
);
9527 gfc_add_block_to_block (&se
->pre
, &se
->post
);
9531 /* Helper to translate an expression and convert it to a particular type. */
9533 gfc_conv_expr_type (gfc_se
* se
, gfc_expr
* expr
, tree type
)
9535 gfc_conv_expr_val (se
, expr
);
9536 se
->expr
= convert (type
, se
->expr
);
9540 /* Converts an expression so that it can be passed by reference. Scalar
9544 gfc_conv_expr_reference (gfc_se
* se
, gfc_expr
* expr
)
9550 if (ss
&& ss
->info
->expr
== expr
9551 && ss
->info
->type
== GFC_SS_REFERENCE
)
9553 /* Returns a reference to the scalar evaluated outside the loop
9555 gfc_conv_expr (se
, expr
);
9557 if (expr
->ts
.type
== BT_CHARACTER
9558 && expr
->expr_type
!= EXPR_FUNCTION
)
9559 gfc_conv_string_parameter (se
);
9561 se
->expr
= gfc_build_addr_expr (NULL_TREE
, se
->expr
);
9566 if (expr
->ts
.type
== BT_CHARACTER
)
9568 gfc_conv_expr (se
, expr
);
9569 gfc_conv_string_parameter (se
);
9573 if (expr
->expr_type
== EXPR_VARIABLE
)
9575 se
->want_pointer
= 1;
9576 gfc_conv_expr (se
, expr
);
9579 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
9580 gfc_add_modify (&se
->pre
, var
, se
->expr
);
9581 gfc_add_block_to_block (&se
->pre
, &se
->post
);
9587 if (expr
->expr_type
== EXPR_FUNCTION
9588 && ((expr
->value
.function
.esym
9589 && expr
->value
.function
.esym
->result
9590 && expr
->value
.function
.esym
->result
->attr
.pointer
9591 && !expr
->value
.function
.esym
->result
->attr
.dimension
)
9592 || (!expr
->value
.function
.esym
&& !expr
->ref
9593 && expr
->symtree
->n
.sym
->attr
.pointer
9594 && !expr
->symtree
->n
.sym
->attr
.dimension
)))
9596 se
->want_pointer
= 1;
9597 gfc_conv_expr (se
, expr
);
9598 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
9599 gfc_add_modify (&se
->pre
, var
, se
->expr
);
9604 gfc_conv_expr (se
, expr
);
9606 /* Create a temporary var to hold the value. */
9607 if (TREE_CONSTANT (se
->expr
))
9609 tree tmp
= se
->expr
;
9610 STRIP_TYPE_NOPS (tmp
);
9611 var
= build_decl (input_location
,
9612 CONST_DECL
, NULL
, TREE_TYPE (tmp
));
9613 DECL_INITIAL (var
) = tmp
;
9614 TREE_STATIC (var
) = 1;
9619 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
9620 gfc_add_modify (&se
->pre
, var
, se
->expr
);
9623 if (!expr
->must_finalize
)
9624 gfc_add_block_to_block (&se
->pre
, &se
->post
);
9626 /* Take the address of that value. */
9627 se
->expr
= gfc_build_addr_expr (NULL_TREE
, var
);
9631 /* Get the _len component for an unlimited polymorphic expression. */
9634 trans_get_upoly_len (stmtblock_t
*block
, gfc_expr
*expr
)
9637 gfc_ref
*ref
= expr
->ref
;
9639 gfc_init_se (&se
, NULL
);
9640 while (ref
&& ref
->next
)
9642 gfc_add_len_component (expr
);
9643 gfc_conv_expr (&se
, expr
);
9644 gfc_add_block_to_block (block
, &se
.pre
);
9645 gcc_assert (se
.post
.head
== NULL_TREE
);
9648 gfc_free_ref_list (ref
->next
);
9653 gfc_free_ref_list (expr
->ref
);
9660 /* Assign _vptr and _len components as appropriate. BLOCK should be a
9661 statement-list outside of the scalarizer-loop. When code is generated, that
9662 depends on the scalarized expression, it is added to RSE.PRE.
9663 Returns le's _vptr tree and when set the len expressions in to_lenp and
9664 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9668 trans_class_vptr_len_assignment (stmtblock_t
*block
, gfc_expr
* le
,
9669 gfc_expr
* re
, gfc_se
*rse
,
9670 tree
* to_lenp
, tree
* from_lenp
)
9673 gfc_expr
* vptr_expr
;
9674 tree tmp
, to_len
= NULL_TREE
, from_len
= NULL_TREE
, lhs_vptr
;
9675 bool set_vptr
= false, temp_rhs
= false;
9676 stmtblock_t
*pre
= block
;
9677 tree class_expr
= NULL_TREE
;
9679 /* Create a temporary for complicated expressions. */
9680 if (re
->expr_type
!= EXPR_VARIABLE
&& re
->expr_type
!= EXPR_NULL
9681 && rse
->expr
!= NULL_TREE
&& !DECL_P (rse
->expr
))
9683 if (re
->ts
.type
== BT_CLASS
&& !GFC_CLASS_TYPE_P (TREE_TYPE (rse
->expr
)))
9684 class_expr
= gfc_get_class_from_expr (rse
->expr
);
9687 pre
= &rse
->loop
->pre
;
9691 if (class_expr
!= NULL_TREE
&& UNLIMITED_POLY (re
))
9693 tmp
= TREE_OPERAND (rse
->expr
, 0);
9694 tmp
= gfc_create_var (TREE_TYPE (tmp
), "rhs");
9695 gfc_add_modify (&rse
->pre
, tmp
, TREE_OPERAND (rse
->expr
, 0));
9699 tmp
= gfc_create_var (TREE_TYPE (rse
->expr
), "rhs");
9700 gfc_add_modify (&rse
->pre
, tmp
, rse
->expr
);
9707 /* Get the _vptr for the left-hand side expression. */
9708 gfc_init_se (&se
, NULL
);
9709 vptr_expr
= gfc_find_and_cut_at_last_class_ref (le
);
9710 if (vptr_expr
!= NULL
&& gfc_expr_attr (vptr_expr
).class_ok
)
9712 /* Care about _len for unlimited polymorphic entities. */
9713 if (UNLIMITED_POLY (vptr_expr
)
9714 || (vptr_expr
->ts
.type
== BT_DERIVED
9715 && vptr_expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
))
9716 to_len
= trans_get_upoly_len (block
, vptr_expr
);
9717 gfc_add_vptr_component (vptr_expr
);
9721 vptr_expr
= gfc_lval_expr_from_sym (gfc_find_vtab (&le
->ts
));
9722 se
.want_pointer
= 1;
9723 gfc_conv_expr (&se
, vptr_expr
);
9724 gfc_free_expr (vptr_expr
);
9725 gfc_add_block_to_block (block
, &se
.pre
);
9726 gcc_assert (se
.post
.head
== NULL_TREE
);
9728 STRIP_NOPS (lhs_vptr
);
9730 /* Set the _vptr only when the left-hand side of the assignment is a
9734 /* Get the vptr from the rhs expression only, when it is variable.
9735 Functions are expected to be assigned to a temporary beforehand. */
9736 vptr_expr
= (re
->expr_type
== EXPR_VARIABLE
&& re
->ts
.type
== BT_CLASS
)
9737 ? gfc_find_and_cut_at_last_class_ref (re
)
9739 if (vptr_expr
!= NULL
&& vptr_expr
->ts
.type
== BT_CLASS
)
9741 if (to_len
!= NULL_TREE
)
9743 /* Get the _len information from the rhs. */
9744 if (UNLIMITED_POLY (vptr_expr
)
9745 || (vptr_expr
->ts
.type
== BT_DERIVED
9746 && vptr_expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
))
9747 from_len
= trans_get_upoly_len (block
, vptr_expr
);
9749 gfc_add_vptr_component (vptr_expr
);
9753 if (re
->expr_type
== EXPR_VARIABLE
9754 && DECL_P (re
->symtree
->n
.sym
->backend_decl
)
9755 && DECL_LANG_SPECIFIC (re
->symtree
->n
.sym
->backend_decl
)
9756 && GFC_DECL_SAVED_DESCRIPTOR (re
->symtree
->n
.sym
->backend_decl
)
9757 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9758 re
->symtree
->n
.sym
->backend_decl
))))
9761 se
.expr
= gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9762 re
->symtree
->n
.sym
->backend_decl
));
9764 from_len
= gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9765 re
->symtree
->n
.sym
->backend_decl
));
9767 else if (temp_rhs
&& re
->ts
.type
== BT_CLASS
)
9772 else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse
->expr
)))
9773 tmp
= gfc_get_class_from_expr (rse
->expr
);
9777 se
.expr
= gfc_class_vptr_get (tmp
);
9778 if (UNLIMITED_POLY (re
))
9779 from_len
= gfc_class_len_get (tmp
);
9782 else if (re
->expr_type
!= EXPR_NULL
)
9783 /* Only when rhs is non-NULL use its declared type for vptr
9785 vptr_expr
= gfc_lval_expr_from_sym (gfc_find_vtab (&re
->ts
));
9787 /* When the rhs is NULL use the vtab of lhs' declared type. */
9788 vptr_expr
= gfc_lval_expr_from_sym (gfc_find_vtab (&le
->ts
));
9793 gfc_init_se (&se
, NULL
);
9794 se
.want_pointer
= 1;
9795 gfc_conv_expr (&se
, vptr_expr
);
9796 gfc_free_expr (vptr_expr
);
9797 gfc_add_block_to_block (block
, &se
.pre
);
9798 gcc_assert (se
.post
.head
== NULL_TREE
);
9800 gfc_add_modify (pre
, lhs_vptr
, fold_convert (TREE_TYPE (lhs_vptr
),
9803 if (to_len
!= NULL_TREE
)
9805 /* The _len component needs to be set. Figure how to get the
9806 value of the right-hand side. */
9807 if (from_len
== NULL_TREE
)
9809 if (rse
->string_length
!= NULL_TREE
)
9810 from_len
= rse
->string_length
;
9811 else if (re
->ts
.type
== BT_CHARACTER
&& re
->ts
.u
.cl
->length
)
9813 gfc_init_se (&se
, NULL
);
9814 gfc_conv_expr (&se
, re
->ts
.u
.cl
->length
);
9815 gfc_add_block_to_block (block
, &se
.pre
);
9816 gcc_assert (se
.post
.head
== NULL_TREE
);
9817 from_len
= gfc_evaluate_now (se
.expr
, block
);
9820 from_len
= build_zero_cst (gfc_charlen_type_node
);
9822 gfc_add_modify (pre
, to_len
, fold_convert (TREE_TYPE (to_len
),
9827 /* Return the _len trees only, when requested. */
9831 *from_lenp
= from_len
;
9836 /* Assign tokens for pointer components. */
9839 trans_caf_token_assign (gfc_se
*lse
, gfc_se
*rse
, gfc_expr
*expr1
,
9842 symbol_attribute lhs_attr
, rhs_attr
;
9843 tree tmp
, lhs_tok
, rhs_tok
;
9844 /* Flag to indicated component refs on the rhs. */
9847 lhs_attr
= gfc_caf_attr (expr1
);
9848 if (expr2
->expr_type
!= EXPR_NULL
)
9850 rhs_attr
= gfc_caf_attr (expr2
, false, &rhs_cr
);
9851 if (lhs_attr
.codimension
&& rhs_attr
.codimension
)
9853 lhs_tok
= gfc_get_ultimate_alloc_ptr_comps_caf_token (lse
, expr1
);
9854 lhs_tok
= build_fold_indirect_ref (lhs_tok
);
9857 rhs_tok
= gfc_get_ultimate_alloc_ptr_comps_caf_token (rse
, expr2
);
9861 caf_decl
= gfc_get_tree_for_caf_expr (expr2
);
9862 gfc_get_caf_token_offset (rse
, &rhs_tok
, NULL
, caf_decl
,
9865 tmp
= build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
9867 fold_convert (TREE_TYPE (lhs_tok
), rhs_tok
));
9868 gfc_prepend_expr_to_block (&lse
->post
, tmp
);
9871 else if (lhs_attr
.codimension
)
9873 lhs_tok
= gfc_get_ultimate_alloc_ptr_comps_caf_token (lse
, expr1
);
9874 lhs_tok
= build_fold_indirect_ref (lhs_tok
);
9875 tmp
= build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
9876 lhs_tok
, null_pointer_node
);
9877 gfc_prepend_expr_to_block (&lse
->post
, tmp
);
9882 /* Do everything that is needed for a CLASS function expr2. */
9885 trans_class_pointer_fcn (stmtblock_t
*block
, gfc_se
*lse
, gfc_se
*rse
,
9886 gfc_expr
*expr1
, gfc_expr
*expr2
)
9888 tree expr1_vptr
= NULL_TREE
;
9891 gfc_conv_function_expr (rse
, expr2
);
9892 rse
->expr
= gfc_evaluate_now (rse
->expr
, &rse
->pre
);
9894 if (expr1
->ts
.type
!= BT_CLASS
)
9895 rse
->expr
= gfc_class_data_get (rse
->expr
);
9898 expr1_vptr
= trans_class_vptr_len_assignment (block
, expr1
,
9901 gfc_add_block_to_block (block
, &rse
->pre
);
9902 tmp
= gfc_create_var (TREE_TYPE (rse
->expr
), "ptrtemp");
9903 gfc_add_modify (&lse
->pre
, tmp
, rse
->expr
);
9905 gfc_add_modify (&lse
->pre
, expr1_vptr
,
9906 fold_convert (TREE_TYPE (expr1_vptr
),
9907 gfc_class_vptr_get (tmp
)));
9908 rse
->expr
= gfc_class_data_get (tmp
);
9916 gfc_trans_pointer_assign (gfc_code
* code
)
9918 return gfc_trans_pointer_assignment (code
->expr1
, code
->expr2
);
9922 /* Generate code for a pointer assignment. */
9925 gfc_trans_pointer_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
)
9932 tree expr1_vptr
= NULL_TREE
;
9933 bool scalar
, non_proc_ptr_assign
;
9936 gfc_start_block (&block
);
9938 gfc_init_se (&lse
, NULL
);
9940 /* Usually testing whether this is not a proc pointer assignment. */
9941 non_proc_ptr_assign
= !(gfc_expr_attr (expr1
).proc_pointer
9942 && expr2
->expr_type
== EXPR_VARIABLE
9943 && expr2
->symtree
->n
.sym
->attr
.flavor
== FL_PROCEDURE
);
9945 /* Check whether the expression is a scalar or not; we cannot use
9946 expr1->rank as it can be nonzero for proc pointers. */
9947 ss
= gfc_walk_expr (expr1
);
9948 scalar
= ss
== gfc_ss_terminator
;
9950 gfc_free_ss_chain (ss
);
9952 if (expr1
->ts
.type
== BT_DERIVED
&& expr2
->ts
.type
== BT_CLASS
9953 && expr2
->expr_type
!= EXPR_FUNCTION
&& non_proc_ptr_assign
)
9955 gfc_add_data_component (expr2
);
9956 /* The following is required as gfc_add_data_component doesn't
9957 update ts.type if there is a trailing REF_ARRAY. */
9958 expr2
->ts
.type
= BT_DERIVED
;
9963 /* Scalar pointers. */
9964 lse
.want_pointer
= 1;
9965 gfc_conv_expr (&lse
, expr1
);
9966 gfc_init_se (&rse
, NULL
);
9967 rse
.want_pointer
= 1;
9968 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->ts
.type
== BT_CLASS
)
9969 trans_class_pointer_fcn (&block
, &lse
, &rse
, expr1
, expr2
);
9971 gfc_conv_expr (&rse
, expr2
);
9973 if (non_proc_ptr_assign
&& expr1
->ts
.type
== BT_CLASS
)
9975 trans_class_vptr_len_assignment (&block
, expr1
, expr2
, &rse
, NULL
,
9977 lse
.expr
= gfc_class_data_get (lse
.expr
);
9980 if (expr1
->symtree
->n
.sym
->attr
.proc_pointer
9981 && expr1
->symtree
->n
.sym
->attr
.dummy
)
9982 lse
.expr
= build_fold_indirect_ref_loc (input_location
,
9985 if (expr2
->symtree
&& expr2
->symtree
->n
.sym
->attr
.proc_pointer
9986 && expr2
->symtree
->n
.sym
->attr
.dummy
)
9987 rse
.expr
= build_fold_indirect_ref_loc (input_location
,
9990 gfc_add_block_to_block (&block
, &lse
.pre
);
9991 gfc_add_block_to_block (&block
, &rse
.pre
);
9993 /* Check character lengths if character expression. The test is only
9994 really added if -fbounds-check is enabled. Exclude deferred
9995 character length lefthand sides. */
9996 if (expr1
->ts
.type
== BT_CHARACTER
&& expr2
->expr_type
!= EXPR_NULL
9997 && !expr1
->ts
.deferred
9998 && !expr1
->symtree
->n
.sym
->attr
.proc_pointer
9999 && !gfc_is_proc_ptr_comp (expr1
))
10001 gcc_assert (expr2
->ts
.type
== BT_CHARACTER
);
10002 gcc_assert (lse
.string_length
&& rse
.string_length
);
10003 gfc_trans_same_strlen_check ("pointer assignment", &expr1
->where
,
10004 lse
.string_length
, rse
.string_length
,
10008 /* The assignment to an deferred character length sets the string
10009 length to that of the rhs. */
10010 if (expr1
->ts
.deferred
)
10012 if (expr2
->expr_type
!= EXPR_NULL
&& lse
.string_length
!= NULL
)
10013 gfc_add_modify (&block
, lse
.string_length
,
10014 fold_convert (TREE_TYPE (lse
.string_length
),
10015 rse
.string_length
));
10016 else if (lse
.string_length
!= NULL
)
10017 gfc_add_modify (&block
, lse
.string_length
,
10018 build_zero_cst (TREE_TYPE (lse
.string_length
)));
10021 gfc_add_modify (&block
, lse
.expr
,
10022 fold_convert (TREE_TYPE (lse
.expr
), rse
.expr
));
10024 /* Also set the tokens for pointer components in derived typed
10026 if (flag_coarray
== GFC_FCOARRAY_LIB
)
10027 trans_caf_token_assign (&lse
, &rse
, expr1
, expr2
);
10029 gfc_add_block_to_block (&block
, &rse
.post
);
10030 gfc_add_block_to_block (&block
, &lse
.post
);
10037 tree strlen_rhs
= NULL_TREE
;
10039 /* Array pointer. Find the last reference on the LHS and if it is an
10040 array section ref, we're dealing with bounds remapping. In this case,
10041 set it to AR_FULL so that gfc_conv_expr_descriptor does
10042 not see it and process the bounds remapping afterwards explicitly. */
10043 for (remap
= expr1
->ref
; remap
; remap
= remap
->next
)
10044 if (!remap
->next
&& remap
->type
== REF_ARRAY
10045 && remap
->u
.ar
.type
== AR_SECTION
)
10047 rank_remap
= (remap
&& remap
->u
.ar
.end
[0]);
10049 if (remap
&& expr2
->expr_type
== EXPR_NULL
)
10051 gfc_error ("If bounds remapping is specified at %L, "
10052 "the pointer target shall not be NULL", &expr1
->where
);
10056 gfc_init_se (&lse
, NULL
);
10058 lse
.descriptor_only
= 1;
10059 gfc_conv_expr_descriptor (&lse
, expr1
);
10060 strlen_lhs
= lse
.string_length
;
10063 if (expr2
->expr_type
== EXPR_NULL
)
10065 /* Just set the data pointer to null. */
10066 gfc_conv_descriptor_data_set (&lse
.pre
, lse
.expr
, null_pointer_node
);
10068 else if (rank_remap
)
10070 /* If we are rank-remapping, just get the RHS's descriptor and
10071 process this later on. */
10072 gfc_init_se (&rse
, NULL
);
10073 rse
.direct_byref
= 1;
10074 rse
.byref_noassign
= 1;
10076 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->ts
.type
== BT_CLASS
)
10077 expr1_vptr
= trans_class_pointer_fcn (&block
, &lse
, &rse
,
10079 else if (expr2
->expr_type
== EXPR_FUNCTION
)
10081 tree bound
[GFC_MAX_DIMENSIONS
];
10084 for (i
= 0; i
< expr2
->rank
; i
++)
10085 bound
[i
] = NULL_TREE
;
10086 tmp
= gfc_typenode_for_spec (&expr2
->ts
);
10087 tmp
= gfc_get_array_type_bounds (tmp
, expr2
->rank
, 0,
10089 GFC_ARRAY_POINTER_CONT
, false);
10090 tmp
= gfc_create_var (tmp
, "ptrtemp");
10091 rse
.descriptor_only
= 0;
10093 rse
.direct_byref
= 1;
10094 gfc_conv_expr_descriptor (&rse
, expr2
);
10095 strlen_rhs
= rse
.string_length
;
10100 gfc_conv_expr_descriptor (&rse
, expr2
);
10101 strlen_rhs
= rse
.string_length
;
10102 if (expr1
->ts
.type
== BT_CLASS
)
10103 expr1_vptr
= trans_class_vptr_len_assignment (&block
, expr1
,
10108 else if (expr2
->expr_type
== EXPR_VARIABLE
)
10110 /* Assign directly to the LHS's descriptor. */
10111 lse
.descriptor_only
= 0;
10112 lse
.direct_byref
= 1;
10113 gfc_conv_expr_descriptor (&lse
, expr2
);
10114 strlen_rhs
= lse
.string_length
;
10115 gfc_init_se (&rse
, NULL
);
10117 if (expr1
->ts
.type
== BT_CLASS
)
10119 rse
.expr
= NULL_TREE
;
10120 rse
.string_length
= strlen_rhs
;
10121 trans_class_vptr_len_assignment (&block
, expr1
, expr2
, &rse
,
10127 /* If the target is not a whole array, use the target array
10128 reference for remap. */
10129 for (remap
= expr2
->ref
; remap
; remap
= remap
->next
)
10130 if (remap
->type
== REF_ARRAY
10131 && remap
->u
.ar
.type
== AR_FULL
10136 else if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->ts
.type
== BT_CLASS
)
10138 gfc_init_se (&rse
, NULL
);
10139 rse
.want_pointer
= 1;
10140 gfc_conv_function_expr (&rse
, expr2
);
10141 if (expr1
->ts
.type
!= BT_CLASS
)
10143 rse
.expr
= gfc_class_data_get (rse
.expr
);
10144 gfc_add_modify (&lse
.pre
, desc
, rse
.expr
);
10145 /* Set the lhs span. */
10146 tmp
= TREE_TYPE (rse
.expr
);
10147 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (tmp
));
10148 tmp
= fold_convert (gfc_array_index_type
, tmp
);
10149 gfc_conv_descriptor_span_set (&lse
.pre
, desc
, tmp
);
10153 expr1_vptr
= trans_class_vptr_len_assignment (&block
, expr1
,
10156 gfc_add_block_to_block (&block
, &rse
.pre
);
10157 tmp
= gfc_create_var (TREE_TYPE (rse
.expr
), "ptrtemp");
10158 gfc_add_modify (&lse
.pre
, tmp
, rse
.expr
);
10160 gfc_add_modify (&lse
.pre
, expr1_vptr
,
10161 fold_convert (TREE_TYPE (expr1_vptr
),
10162 gfc_class_vptr_get (tmp
)));
10163 rse
.expr
= gfc_class_data_get (tmp
);
10164 gfc_add_modify (&lse
.pre
, desc
, rse
.expr
);
10169 /* Assign to a temporary descriptor and then copy that
10170 temporary to the pointer. */
10171 tmp
= gfc_create_var (TREE_TYPE (desc
), "ptrtemp");
10172 lse
.descriptor_only
= 0;
10174 lse
.direct_byref
= 1;
10175 gfc_conv_expr_descriptor (&lse
, expr2
);
10176 strlen_rhs
= lse
.string_length
;
10177 gfc_add_modify (&lse
.pre
, desc
, tmp
);
10180 if (expr1
->ts
.type
== BT_CHARACTER
10181 && expr1
->symtree
->n
.sym
->ts
.deferred
10182 && expr1
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
10183 && VAR_P (expr1
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
))
10185 tmp
= expr1
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
;
10186 if (expr2
->expr_type
!= EXPR_NULL
)
10187 gfc_add_modify (&block
, tmp
,
10188 fold_convert (TREE_TYPE (tmp
), strlen_rhs
));
10190 gfc_add_modify (&block
, tmp
, build_zero_cst (TREE_TYPE (tmp
)));
10193 gfc_add_block_to_block (&block
, &lse
.pre
);
10195 gfc_add_block_to_block (&block
, &rse
.pre
);
10197 /* If we do bounds remapping, update LHS descriptor accordingly. */
10201 gcc_assert (remap
->u
.ar
.dimen
== expr1
->rank
);
10205 /* Do rank remapping. We already have the RHS's descriptor
10206 converted in rse and now have to build the correct LHS
10207 descriptor for it. */
10209 tree dtype
, data
, span
;
10211 tree lbound
, ubound
;
10214 dtype
= gfc_conv_descriptor_dtype (desc
);
10215 tmp
= gfc_get_dtype (TREE_TYPE (desc
));
10216 gfc_add_modify (&block
, dtype
, tmp
);
10218 /* Copy data pointer. */
10219 data
= gfc_conv_descriptor_data_get (rse
.expr
);
10220 gfc_conv_descriptor_data_set (&block
, desc
, data
);
10222 /* Copy the span. */
10223 if (TREE_CODE (rse
.expr
) == VAR_DECL
10224 && GFC_DECL_PTR_ARRAY_P (rse
.expr
))
10225 span
= gfc_conv_descriptor_span_get (rse
.expr
);
10228 tmp
= TREE_TYPE (rse
.expr
);
10229 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (tmp
));
10230 span
= fold_convert (gfc_array_index_type
, tmp
);
10232 gfc_conv_descriptor_span_set (&block
, desc
, span
);
10234 /* Copy offset but adjust it such that it would correspond
10235 to a lbound of zero. */
10236 offs
= gfc_conv_descriptor_offset_get (rse
.expr
);
10237 for (dim
= 0; dim
< expr2
->rank
; ++dim
)
10239 stride
= gfc_conv_descriptor_stride_get (rse
.expr
,
10240 gfc_rank_cst
[dim
]);
10241 lbound
= gfc_conv_descriptor_lbound_get (rse
.expr
,
10242 gfc_rank_cst
[dim
]);
10243 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
10244 gfc_array_index_type
, stride
, lbound
);
10245 offs
= fold_build2_loc (input_location
, PLUS_EXPR
,
10246 gfc_array_index_type
, offs
, tmp
);
10248 gfc_conv_descriptor_offset_set (&block
, desc
, offs
);
10250 /* Set the bounds as declared for the LHS and calculate strides as
10251 well as another offset update accordingly. */
10252 stride
= gfc_conv_descriptor_stride_get (rse
.expr
,
10254 for (dim
= 0; dim
< expr1
->rank
; ++dim
)
10259 gcc_assert (remap
->u
.ar
.start
[dim
] && remap
->u
.ar
.end
[dim
]);
10261 /* Convert declared bounds. */
10262 gfc_init_se (&lower_se
, NULL
);
10263 gfc_init_se (&upper_se
, NULL
);
10264 gfc_conv_expr (&lower_se
, remap
->u
.ar
.start
[dim
]);
10265 gfc_conv_expr (&upper_se
, remap
->u
.ar
.end
[dim
]);
10267 gfc_add_block_to_block (&block
, &lower_se
.pre
);
10268 gfc_add_block_to_block (&block
, &upper_se
.pre
);
10270 lbound
= fold_convert (gfc_array_index_type
, lower_se
.expr
);
10271 ubound
= fold_convert (gfc_array_index_type
, upper_se
.expr
);
10273 lbound
= gfc_evaluate_now (lbound
, &block
);
10274 ubound
= gfc_evaluate_now (ubound
, &block
);
10276 gfc_add_block_to_block (&block
, &lower_se
.post
);
10277 gfc_add_block_to_block (&block
, &upper_se
.post
);
10279 /* Set bounds in descriptor. */
10280 gfc_conv_descriptor_lbound_set (&block
, desc
,
10281 gfc_rank_cst
[dim
], lbound
);
10282 gfc_conv_descriptor_ubound_set (&block
, desc
,
10283 gfc_rank_cst
[dim
], ubound
);
10286 stride
= gfc_evaluate_now (stride
, &block
);
10287 gfc_conv_descriptor_stride_set (&block
, desc
,
10288 gfc_rank_cst
[dim
], stride
);
10290 /* Update offset. */
10291 offs
= gfc_conv_descriptor_offset_get (desc
);
10292 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
10293 gfc_array_index_type
, lbound
, stride
);
10294 offs
= fold_build2_loc (input_location
, MINUS_EXPR
,
10295 gfc_array_index_type
, offs
, tmp
);
10296 offs
= gfc_evaluate_now (offs
, &block
);
10297 gfc_conv_descriptor_offset_set (&block
, desc
, offs
);
10299 /* Update stride. */
10300 tmp
= gfc_conv_array_extent_dim (lbound
, ubound
, NULL
);
10301 stride
= fold_build2_loc (input_location
, MULT_EXPR
,
10302 gfc_array_index_type
, stride
, tmp
);
10307 /* Bounds remapping. Just shift the lower bounds. */
10309 gcc_assert (expr1
->rank
== expr2
->rank
);
10311 for (dim
= 0; dim
< remap
->u
.ar
.dimen
; ++dim
)
10315 gcc_assert (!remap
->u
.ar
.end
[dim
]);
10316 gfc_init_se (&lbound_se
, NULL
);
10317 if (remap
->u
.ar
.start
[dim
])
10319 gfc_conv_expr (&lbound_se
, remap
->u
.ar
.start
[dim
]);
10320 gfc_add_block_to_block (&block
, &lbound_se
.pre
);
10323 /* This remap arises from a target that is not a whole
10324 array. The start expressions will be NULL but we need
10325 the lbounds to be one. */
10326 lbound_se
.expr
= gfc_index_one_node
;
10327 gfc_conv_shift_descriptor_lbound (&block
, desc
,
10328 dim
, lbound_se
.expr
);
10329 gfc_add_block_to_block (&block
, &lbound_se
.post
);
10334 /* If rank remapping was done, check with -fcheck=bounds that
10335 the target is at least as large as the pointer. */
10336 if (rank_remap
&& (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
))
10342 lsize
= gfc_conv_descriptor_size (lse
.expr
, expr1
->rank
);
10343 rsize
= gfc_conv_descriptor_size (rse
.expr
, expr2
->rank
);
10345 lsize
= gfc_evaluate_now (lsize
, &block
);
10346 rsize
= gfc_evaluate_now (rsize
, &block
);
10347 fault
= fold_build2_loc (input_location
, LT_EXPR
, logical_type_node
,
10350 msg
= _("Target of rank remapping is too small (%ld < %ld)");
10351 gfc_trans_runtime_check (true, false, fault
, &block
, &expr2
->where
,
10352 msg
, rsize
, lsize
);
10355 /* Check string lengths if applicable. The check is only really added
10356 to the output code if -fbounds-check is enabled. */
10357 if (expr1
->ts
.type
== BT_CHARACTER
&& expr2
->expr_type
!= EXPR_NULL
)
10359 gcc_assert (expr2
->ts
.type
== BT_CHARACTER
);
10360 gcc_assert (strlen_lhs
&& strlen_rhs
);
10361 gfc_trans_same_strlen_check ("pointer assignment", &expr1
->where
,
10362 strlen_lhs
, strlen_rhs
, &block
);
10365 gfc_add_block_to_block (&block
, &lse
.post
);
10367 gfc_add_block_to_block (&block
, &rse
.post
);
10370 return gfc_finish_block (&block
);
10374 /* Makes sure se is suitable for passing as a function string parameter. */
10375 /* TODO: Need to check all callers of this function. It may be abused. */
10378 gfc_conv_string_parameter (gfc_se
* se
)
10382 if (TREE_CODE (se
->expr
) == STRING_CST
)
10384 type
= TREE_TYPE (TREE_TYPE (se
->expr
));
10385 se
->expr
= gfc_build_addr_expr (build_pointer_type (type
), se
->expr
);
10389 if ((TREE_CODE (TREE_TYPE (se
->expr
)) == ARRAY_TYPE
10390 || TREE_CODE (TREE_TYPE (se
->expr
)) == INTEGER_TYPE
)
10391 && TYPE_STRING_FLAG (TREE_TYPE (se
->expr
)))
10393 type
= TREE_TYPE (se
->expr
);
10394 if (TREE_CODE (se
->expr
) != INDIRECT_REF
)
10395 se
->expr
= gfc_build_addr_expr (build_pointer_type (type
), se
->expr
);
10398 if (TREE_CODE (type
) == ARRAY_TYPE
)
10399 type
= TREE_TYPE (type
);
10400 type
= gfc_get_character_type_len_for_eltype (type
,
10401 se
->string_length
);
10402 type
= build_pointer_type (type
);
10403 se
->expr
= gfc_build_addr_expr (type
, se
->expr
);
10407 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se
->expr
)));
10411 /* Generate code for assignment of scalar variables. Includes character
10412 strings and derived types with allocatable components.
10413 If you know that the LHS has no allocations, set dealloc to false.
10415 DEEP_COPY has no effect if the typespec TS is not a derived type with
10416 allocatable components. Otherwise, if it is set, an explicit copy of each
10417 allocatable component is made. This is necessary as a simple copy of the
10418 whole object would copy array descriptors as is, so that the lhs's
10419 allocatable components would point to the rhs's after the assignment.
10420 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
10421 necessary if the rhs is a non-pointer function, as the allocatable components
10422 are not accessible by other means than the function's result after the
10423 function has returned. It is even more subtle when temporaries are involved,
10424 as the two following examples show:
10425 1. When we evaluate an array constructor, a temporary is created. Thus
10426 there is theoretically no alias possible. However, no deep copy is
10427 made for this temporary, so that if the constructor is made of one or
10428 more variable with allocatable components, those components still point
10429 to the variable's: DEEP_COPY should be set for the assignment from the
10430 temporary to the lhs in that case.
10431 2. When assigning a scalar to an array, we evaluate the scalar value out
10432 of the loop, store it into a temporary variable, and assign from that.
10433 In that case, deep copying when assigning to the temporary would be a
10434 waste of resources; however deep copies should happen when assigning from
10435 the temporary to each array element: again DEEP_COPY should be set for
10436 the assignment from the temporary to the lhs. */
10439 gfc_trans_scalar_assign (gfc_se
* lse
, gfc_se
* rse
, gfc_typespec ts
,
10440 bool deep_copy
, bool dealloc
, bool in_coarray
)
10446 gfc_init_block (&block
);
10448 if (ts
.type
== BT_CHARACTER
)
10453 if (lse
->string_length
!= NULL_TREE
)
10455 gfc_conv_string_parameter (lse
);
10456 gfc_add_block_to_block (&block
, &lse
->pre
);
10457 llen
= lse
->string_length
;
10460 if (rse
->string_length
!= NULL_TREE
)
10462 gfc_conv_string_parameter (rse
);
10463 gfc_add_block_to_block (&block
, &rse
->pre
);
10464 rlen
= rse
->string_length
;
10467 gfc_trans_string_copy (&block
, llen
, lse
->expr
, ts
.kind
, rlen
,
10468 rse
->expr
, ts
.kind
);
10470 else if (gfc_bt_struct (ts
.type
)
10471 && (ts
.u
.derived
->attr
.alloc_comp
10472 || (deep_copy
&& ts
.u
.derived
->attr
.pdt_type
)))
10474 tree tmp_var
= NULL_TREE
;
10477 /* Are the rhs and the lhs the same? */
10480 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
10481 gfc_build_addr_expr (NULL_TREE
, lse
->expr
),
10482 gfc_build_addr_expr (NULL_TREE
, rse
->expr
));
10483 cond
= gfc_evaluate_now (cond
, &lse
->pre
);
10486 /* Deallocate the lhs allocated components as long as it is not
10487 the same as the rhs. This must be done following the assignment
10488 to prevent deallocating data that could be used in the rhs
10492 tmp_var
= gfc_evaluate_now (lse
->expr
, &lse
->pre
);
10493 tmp
= gfc_deallocate_alloc_comp_no_caf (ts
.u
.derived
, tmp_var
, 0);
10495 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (input_location
),
10497 gfc_add_expr_to_block (&lse
->post
, tmp
);
10500 gfc_add_block_to_block (&block
, &rse
->pre
);
10501 gfc_add_block_to_block (&block
, &lse
->pre
);
10503 gfc_add_modify (&block
, lse
->expr
,
10504 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
10506 /* Restore pointer address of coarray components. */
10507 if (ts
.u
.derived
->attr
.coarray_comp
&& deep_copy
&& tmp_var
!= NULL_TREE
)
10509 tmp
= gfc_reassign_alloc_comp_caf (ts
.u
.derived
, tmp_var
, lse
->expr
);
10510 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (input_location
),
10512 gfc_add_expr_to_block (&block
, tmp
);
10515 /* Do a deep copy if the rhs is a variable, if it is not the
10516 same as the lhs. */
10519 int caf_mode
= in_coarray
? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10520 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY
) : 0;
10521 tmp
= gfc_copy_alloc_comp (ts
.u
.derived
, rse
->expr
, lse
->expr
, 0,
10523 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (input_location
),
10525 gfc_add_expr_to_block (&block
, tmp
);
10528 else if (gfc_bt_struct (ts
.type
))
10530 gfc_add_block_to_block (&block
, &lse
->pre
);
10531 gfc_add_block_to_block (&block
, &rse
->pre
);
10532 tmp
= fold_build1_loc (input_location
, VIEW_CONVERT_EXPR
,
10533 TREE_TYPE (lse
->expr
), rse
->expr
);
10534 gfc_add_modify (&block
, lse
->expr
, tmp
);
10536 /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
10537 else if (ts
.type
== BT_CLASS
)
10539 gfc_add_block_to_block (&block
, &lse
->pre
);
10540 gfc_add_block_to_block (&block
, &rse
->pre
);
10542 if (!trans_scalar_class_assign (&block
, lse
, rse
))
10544 /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10545 for the lhs which ensures that class data rhs cast as a string assigns
10547 tmp
= fold_build1_loc (input_location
, VIEW_CONVERT_EXPR
,
10548 TREE_TYPE (rse
->expr
), lse
->expr
);
10549 gfc_add_modify (&block
, tmp
, rse
->expr
);
10552 else if (ts
.type
!= BT_CLASS
)
10554 gfc_add_block_to_block (&block
, &lse
->pre
);
10555 gfc_add_block_to_block (&block
, &rse
->pre
);
10557 gfc_add_modify (&block
, lse
->expr
,
10558 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
10561 gfc_add_block_to_block (&block
, &lse
->post
);
10562 gfc_add_block_to_block (&block
, &rse
->post
);
10564 return gfc_finish_block (&block
);
10568 /* There are quite a lot of restrictions on the optimisation in using an
10569 array function assign without a temporary. */
10572 arrayfunc_assign_needs_temporary (gfc_expr
* expr1
, gfc_expr
* expr2
)
10575 bool seen_array_ref
;
10577 gfc_symbol
*sym
= expr1
->symtree
->n
.sym
;
10579 /* Play it safe with class functions assigned to a derived type. */
10580 if (gfc_is_class_array_function (expr2
)
10581 && expr1
->ts
.type
== BT_DERIVED
)
10584 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10585 if (expr2
->value
.function
.isym
&& !gfc_is_intrinsic_libcall (expr2
))
10588 /* Elemental functions are scalarized so that they don't need a
10589 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10590 they would need special treatment in gfc_trans_arrayfunc_assign. */
10591 if (expr2
->value
.function
.esym
!= NULL
10592 && expr2
->value
.function
.esym
->attr
.elemental
)
10595 /* Need a temporary if rhs is not FULL or a contiguous section. */
10596 if (expr1
->ref
&& !(gfc_full_array_ref_p (expr1
->ref
, &c
) || c
))
10599 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
10600 if (gfc_ref_needs_temporary_p (expr1
->ref
))
10603 /* Functions returning pointers or allocatables need temporaries. */
10604 if (gfc_expr_attr (expr2
).pointer
10605 || gfc_expr_attr (expr2
).allocatable
)
10608 /* Character array functions need temporaries unless the
10609 character lengths are the same. */
10610 if (expr2
->ts
.type
== BT_CHARACTER
&& expr2
->rank
> 0)
10612 if (expr1
->ts
.u
.cl
->length
== NULL
10613 || expr1
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
10616 if (expr2
->ts
.u
.cl
->length
== NULL
10617 || expr2
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
10620 if (mpz_cmp (expr1
->ts
.u
.cl
->length
->value
.integer
,
10621 expr2
->ts
.u
.cl
->length
->value
.integer
) != 0)
10625 /* Check that no LHS component references appear during an array
10626 reference. This is needed because we do not have the means to
10627 span any arbitrary stride with an array descriptor. This check
10628 is not needed for the rhs because the function result has to be
10629 a complete type. */
10630 seen_array_ref
= false;
10631 for (ref
= expr1
->ref
; ref
; ref
= ref
->next
)
10633 if (ref
->type
== REF_ARRAY
)
10634 seen_array_ref
= true;
10635 else if (ref
->type
== REF_COMPONENT
&& seen_array_ref
)
10639 /* Check for a dependency. */
10640 if (gfc_check_fncall_dependency (expr1
, INTENT_OUT
,
10641 expr2
->value
.function
.esym
,
10642 expr2
->value
.function
.actual
,
10646 /* If we have reached here with an intrinsic function, we do not
10647 need a temporary except in the particular case that reallocation
10648 on assignment is active and the lhs is allocatable and a target,
10649 or a pointer which may be a subref pointer. FIXME: The last
10650 condition can go away when we use span in the intrinsics
10652 if (expr2
->value
.function
.isym
)
10653 return (flag_realloc_lhs
&& sym
->attr
.allocatable
&& sym
->attr
.target
)
10654 || (sym
->attr
.pointer
&& sym
->attr
.subref_array_pointer
);
10656 /* If the LHS is a dummy, we need a temporary if it is not
10658 if (sym
->attr
.dummy
&& sym
->attr
.intent
!= INTENT_OUT
)
10661 /* If the lhs has been host_associated, is in common, a pointer or is
10662 a target and the function is not using a RESULT variable, aliasing
10663 can occur and a temporary is needed. */
10664 if ((sym
->attr
.host_assoc
10665 || sym
->attr
.in_common
10666 || sym
->attr
.pointer
10667 || sym
->attr
.cray_pointee
10668 || sym
->attr
.target
)
10669 && expr2
->symtree
!= NULL
10670 && expr2
->symtree
->n
.sym
== expr2
->symtree
->n
.sym
->result
)
10673 /* A PURE function can unconditionally be called without a temporary. */
10674 if (expr2
->value
.function
.esym
!= NULL
10675 && expr2
->value
.function
.esym
->attr
.pure
)
10678 /* Implicit_pure functions are those which could legally be declared
10680 if (expr2
->value
.function
.esym
!= NULL
10681 && expr2
->value
.function
.esym
->attr
.implicit_pure
)
10684 if (!sym
->attr
.use_assoc
10685 && !sym
->attr
.in_common
10686 && !sym
->attr
.pointer
10687 && !sym
->attr
.target
10688 && !sym
->attr
.cray_pointee
10689 && expr2
->value
.function
.esym
)
10691 /* A temporary is not needed if the function is not contained and
10692 the variable is local or host associated and not a pointer or
10694 if (!expr2
->value
.function
.esym
->attr
.contained
)
10697 /* A temporary is not needed if the lhs has never been host
10698 associated and the procedure is contained. */
10699 else if (!sym
->attr
.host_assoc
)
10702 /* A temporary is not needed if the variable is local and not
10703 a pointer, a target or a result. */
10704 if (sym
->ns
->parent
10705 && expr2
->value
.function
.esym
->ns
== sym
->ns
->parent
)
10709 /* Default to temporary use. */
10714 /* Provide the loop info so that the lhs descriptor can be built for
10715 reallocatable assignments from extrinsic function calls. */
10718 realloc_lhs_loop_for_fcn_call (gfc_se
*se
, locus
*where
, gfc_ss
**ss
,
10719 gfc_loopinfo
*loop
)
10721 /* Signal that the function call should not be made by
10722 gfc_conv_loop_setup. */
10723 se
->ss
->is_alloc_lhs
= 1;
10724 gfc_init_loopinfo (loop
);
10725 gfc_add_ss_to_loop (loop
, *ss
);
10726 gfc_add_ss_to_loop (loop
, se
->ss
);
10727 gfc_conv_ss_startstride (loop
);
10728 gfc_conv_loop_setup (loop
, where
);
10729 gfc_copy_loopinfo_to_se (se
, loop
);
10730 gfc_add_block_to_block (&se
->pre
, &loop
->pre
);
10731 gfc_add_block_to_block (&se
->pre
, &loop
->post
);
10732 se
->ss
->is_alloc_lhs
= 0;
10736 /* For assignment to a reallocatable lhs from intrinsic functions,
10737 replace the se.expr (ie. the result) with a temporary descriptor.
10738 Null the data field so that the library allocates space for the
10739 result. Free the data of the original descriptor after the function,
10740 in case it appears in an argument expression and transfer the
10741 result to the original descriptor. */
10744 fcncall_realloc_result (gfc_se
*se
, int rank
)
10751 tree not_same_shape
;
10752 stmtblock_t shape_block
;
10755 /* Use the allocation done by the library. Substitute the lhs
10756 descriptor with a copy, whose data field is nulled.*/
10757 desc
= build_fold_indirect_ref_loc (input_location
, se
->expr
);
10758 if (POINTER_TYPE_P (TREE_TYPE (desc
)))
10759 desc
= build_fold_indirect_ref_loc (input_location
, desc
);
10761 /* Unallocated, the descriptor does not have a dtype. */
10762 tmp
= gfc_conv_descriptor_dtype (desc
);
10763 gfc_add_modify (&se
->pre
, tmp
, gfc_get_dtype (TREE_TYPE (desc
)));
10765 res_desc
= gfc_evaluate_now (desc
, &se
->pre
);
10766 gfc_conv_descriptor_data_set (&se
->pre
, res_desc
, null_pointer_node
);
10767 se
->expr
= gfc_build_addr_expr (NULL_TREE
, res_desc
);
10769 /* Free the lhs after the function call and copy the result data to
10770 the lhs descriptor. */
10771 tmp
= gfc_conv_descriptor_data_get (desc
);
10772 zero_cond
= fold_build2_loc (input_location
, EQ_EXPR
,
10773 logical_type_node
, tmp
,
10774 build_int_cst (TREE_TYPE (tmp
), 0));
10775 zero_cond
= gfc_evaluate_now (zero_cond
, &se
->post
);
10776 tmp
= gfc_call_free (tmp
);
10777 gfc_add_expr_to_block (&se
->post
, tmp
);
10779 tmp
= gfc_conv_descriptor_data_get (res_desc
);
10780 gfc_conv_descriptor_data_set (&se
->post
, desc
, tmp
);
10782 /* Check that the shapes are the same between lhs and expression.
10783 The evaluation of the shape is done in 'shape_block' to avoid
10784 unitialized warnings from the lhs bounds. */
10785 not_same_shape
= boolean_false_node
;
10786 gfc_start_block (&shape_block
);
10787 for (n
= 0 ; n
< rank
; n
++)
10790 tmp
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[n
]);
10791 tmp1
= gfc_conv_descriptor_lbound_get (res_desc
, gfc_rank_cst
[n
]);
10792 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
10793 gfc_array_index_type
, tmp
, tmp1
);
10794 tmp1
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[n
]);
10795 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
10796 gfc_array_index_type
, tmp
, tmp1
);
10797 tmp1
= gfc_conv_descriptor_ubound_get (res_desc
, gfc_rank_cst
[n
]);
10798 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
10799 gfc_array_index_type
, tmp
, tmp1
);
10800 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
10801 logical_type_node
, tmp
,
10802 gfc_index_zero_node
);
10803 tmp
= gfc_evaluate_now (tmp
, &shape_block
);
10805 not_same_shape
= tmp
;
10807 not_same_shape
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
10808 logical_type_node
, tmp
,
10812 /* 'zero_cond' being true is equal to lhs not being allocated or the
10813 shapes being different. */
10814 tmp
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
, logical_type_node
,
10815 zero_cond
, not_same_shape
);
10816 gfc_add_modify (&shape_block
, zero_cond
, tmp
);
10817 tmp
= gfc_finish_block (&shape_block
);
10818 tmp
= build3_v (COND_EXPR
, zero_cond
,
10819 build_empty_stmt (input_location
), tmp
);
10820 gfc_add_expr_to_block (&se
->post
, tmp
);
10822 /* Now reset the bounds returned from the function call to bounds based
10823 on the lhs lbounds, except where the lhs is not allocated or the shapes
10824 of 'variable and 'expr' are different. Set the offset accordingly. */
10825 offset
= gfc_index_zero_node
;
10826 for (n
= 0 ; n
< rank
; n
++)
10830 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[n
]);
10831 lbound
= fold_build3_loc (input_location
, COND_EXPR
,
10832 gfc_array_index_type
, zero_cond
,
10833 gfc_index_one_node
, lbound
);
10834 lbound
= gfc_evaluate_now (lbound
, &se
->post
);
10836 tmp
= gfc_conv_descriptor_ubound_get (res_desc
, gfc_rank_cst
[n
]);
10837 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
10838 gfc_array_index_type
, tmp
, lbound
);
10839 gfc_conv_descriptor_lbound_set (&se
->post
, desc
,
10840 gfc_rank_cst
[n
], lbound
);
10841 gfc_conv_descriptor_ubound_set (&se
->post
, desc
,
10842 gfc_rank_cst
[n
], tmp
);
10844 /* Set stride and accumulate the offset. */
10845 tmp
= gfc_conv_descriptor_stride_get (res_desc
, gfc_rank_cst
[n
]);
10846 gfc_conv_descriptor_stride_set (&se
->post
, desc
,
10847 gfc_rank_cst
[n
], tmp
);
10848 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
10849 gfc_array_index_type
, lbound
, tmp
);
10850 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
10851 gfc_array_index_type
, offset
, tmp
);
10852 offset
= gfc_evaluate_now (offset
, &se
->post
);
10855 gfc_conv_descriptor_offset_set (&se
->post
, desc
, offset
);
10860 /* Try to translate array(:) = func (...), where func is a transformational
10861 array function, without using a temporary. Returns NULL if this isn't the
10865 gfc_trans_arrayfunc_assign (gfc_expr
* expr1
, gfc_expr
* expr2
)
10869 gfc_component
*comp
= NULL
;
10872 if (arrayfunc_assign_needs_temporary (expr1
, expr2
))
10875 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10877 comp
= gfc_get_proc_ptr_comp (expr2
);
10879 if (!(expr2
->value
.function
.isym
10880 || (comp
&& comp
->attr
.dimension
)
10881 || (!comp
&& gfc_return_by_reference (expr2
->value
.function
.esym
)
10882 && expr2
->value
.function
.esym
->result
->attr
.dimension
)))
10885 gfc_init_se (&se
, NULL
);
10886 gfc_start_block (&se
.pre
);
10887 se
.want_pointer
= 1;
10889 gfc_conv_array_parameter (&se
, expr1
, false, NULL
, NULL
, NULL
);
10891 if (expr1
->ts
.type
== BT_DERIVED
10892 && expr1
->ts
.u
.derived
->attr
.alloc_comp
)
10895 tmp
= gfc_deallocate_alloc_comp_no_caf (expr1
->ts
.u
.derived
, se
.expr
,
10897 gfc_add_expr_to_block (&se
.pre
, tmp
);
10900 se
.direct_byref
= 1;
10901 se
.ss
= gfc_walk_expr (expr2
);
10902 gcc_assert (se
.ss
!= gfc_ss_terminator
);
10904 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10905 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10906 Clearly, this cannot be done for an allocatable function result, since
10907 the shape of the result is unknown and, in any case, the function must
10908 correctly take care of the reallocation internally. For intrinsic
10909 calls, the array data is freed and the library takes care of allocation.
10910 TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
10912 if (flag_realloc_lhs
10913 && gfc_is_reallocatable_lhs (expr1
)
10914 && !gfc_expr_attr (expr1
).codimension
10915 && !gfc_is_coindexed (expr1
)
10916 && !(expr2
->value
.function
.esym
10917 && expr2
->value
.function
.esym
->result
->attr
.allocatable
))
10919 realloc_lhs_warning (expr1
->ts
.type
, true, &expr1
->where
);
10921 if (!expr2
->value
.function
.isym
)
10923 ss
= gfc_walk_expr (expr1
);
10924 gcc_assert (ss
!= gfc_ss_terminator
);
10926 realloc_lhs_loop_for_fcn_call (&se
, &expr1
->where
, &ss
, &loop
);
10927 ss
->is_alloc_lhs
= 1;
10930 fcncall_realloc_result (&se
, expr1
->rank
);
10933 gfc_conv_function_expr (&se
, expr2
);
10934 gfc_add_block_to_block (&se
.pre
, &se
.post
);
10937 gfc_cleanup_loop (&loop
);
10939 gfc_free_ss_chain (se
.ss
);
10941 return gfc_finish_block (&se
.pre
);
10945 /* Try to efficiently translate array(:) = 0. Return NULL if this
10949 gfc_trans_zero_assign (gfc_expr
* expr
)
10951 tree dest
, len
, type
;
10955 sym
= expr
->symtree
->n
.sym
;
10956 dest
= gfc_get_symbol_decl (sym
);
10958 type
= TREE_TYPE (dest
);
10959 if (POINTER_TYPE_P (type
))
10960 type
= TREE_TYPE (type
);
10961 if (!GFC_ARRAY_TYPE_P (type
))
10964 /* Determine the length of the array. */
10965 len
= GFC_TYPE_ARRAY_SIZE (type
);
10966 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
10969 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
10970 len
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
, len
,
10971 fold_convert (gfc_array_index_type
, tmp
));
10973 /* If we are zeroing a local array avoid taking its address by emitting
10975 if (!POINTER_TYPE_P (TREE_TYPE (dest
)))
10976 return build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
10977 dest
, build_constructor (TREE_TYPE (dest
),
10980 /* Convert arguments to the correct types. */
10981 dest
= fold_convert (pvoid_type_node
, dest
);
10982 len
= fold_convert (size_type_node
, len
);
10984 /* Construct call to __builtin_memset. */
10985 tmp
= build_call_expr_loc (input_location
,
10986 builtin_decl_explicit (BUILT_IN_MEMSET
),
10987 3, dest
, integer_zero_node
, len
);
10988 return fold_convert (void_type_node
, tmp
);
10992 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10993 that constructs the call to __builtin_memcpy. */
10996 gfc_build_memcpy_call (tree dst
, tree src
, tree len
)
11000 /* Convert arguments to the correct types. */
11001 if (!POINTER_TYPE_P (TREE_TYPE (dst
)))
11002 dst
= gfc_build_addr_expr (pvoid_type_node
, dst
);
11004 dst
= fold_convert (pvoid_type_node
, dst
);
11006 if (!POINTER_TYPE_P (TREE_TYPE (src
)))
11007 src
= gfc_build_addr_expr (pvoid_type_node
, src
);
11009 src
= fold_convert (pvoid_type_node
, src
);
11011 len
= fold_convert (size_type_node
, len
);
11013 /* Construct call to __builtin_memcpy. */
11014 tmp
= build_call_expr_loc (input_location
,
11015 builtin_decl_explicit (BUILT_IN_MEMCPY
),
11017 return fold_convert (void_type_node
, tmp
);
11021 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
11022 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
11023 source/rhs, both are gfc_full_array_ref_p which have been checked for
11027 gfc_trans_array_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
11029 tree dst
, dlen
, dtype
;
11030 tree src
, slen
, stype
;
11033 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
11034 src
= gfc_get_symbol_decl (expr2
->symtree
->n
.sym
);
11036 dtype
= TREE_TYPE (dst
);
11037 if (POINTER_TYPE_P (dtype
))
11038 dtype
= TREE_TYPE (dtype
);
11039 stype
= TREE_TYPE (src
);
11040 if (POINTER_TYPE_P (stype
))
11041 stype
= TREE_TYPE (stype
);
11043 if (!GFC_ARRAY_TYPE_P (dtype
) || !GFC_ARRAY_TYPE_P (stype
))
11046 /* Determine the lengths of the arrays. */
11047 dlen
= GFC_TYPE_ARRAY_SIZE (dtype
);
11048 if (!dlen
|| TREE_CODE (dlen
) != INTEGER_CST
)
11050 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (dtype
));
11051 dlen
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
11052 dlen
, fold_convert (gfc_array_index_type
, tmp
));
11054 slen
= GFC_TYPE_ARRAY_SIZE (stype
);
11055 if (!slen
|| TREE_CODE (slen
) != INTEGER_CST
)
11057 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (stype
));
11058 slen
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
11059 slen
, fold_convert (gfc_array_index_type
, tmp
));
11061 /* Sanity check that they are the same. This should always be
11062 the case, as we should already have checked for conformance. */
11063 if (!tree_int_cst_equal (slen
, dlen
))
11066 return gfc_build_memcpy_call (dst
, src
, dlen
);
11070 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
11071 this can't be done. EXPR1 is the destination/lhs for which
11072 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
11075 gfc_trans_array_constructor_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
11077 unsigned HOST_WIDE_INT nelem
;
11083 nelem
= gfc_constant_array_constructor_p (expr2
->value
.constructor
);
11087 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
11088 dtype
= TREE_TYPE (dst
);
11089 if (POINTER_TYPE_P (dtype
))
11090 dtype
= TREE_TYPE (dtype
);
11091 if (!GFC_ARRAY_TYPE_P (dtype
))
11094 /* Determine the lengths of the array. */
11095 len
= GFC_TYPE_ARRAY_SIZE (dtype
);
11096 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
11099 /* Confirm that the constructor is the same size. */
11100 if (compare_tree_int (len
, nelem
) != 0)
11103 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (dtype
));
11104 len
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
, len
,
11105 fold_convert (gfc_array_index_type
, tmp
));
11107 stype
= gfc_typenode_for_spec (&expr2
->ts
);
11108 src
= gfc_build_constant_array_constructor (expr2
, stype
);
11110 return gfc_build_memcpy_call (dst
, src
, len
);
11114 /* Tells whether the expression is to be treated as a variable reference. */
11117 gfc_expr_is_variable (gfc_expr
*expr
)
11120 gfc_component
*comp
;
11121 gfc_symbol
*func_ifc
;
11123 if (expr
->expr_type
== EXPR_VARIABLE
)
11126 arg
= gfc_get_noncopying_intrinsic_argument (expr
);
11129 gcc_assert (expr
->value
.function
.isym
->id
== GFC_ISYM_TRANSPOSE
);
11130 return gfc_expr_is_variable (arg
);
11133 /* A data-pointer-returning function should be considered as a variable
11135 if (expr
->expr_type
== EXPR_FUNCTION
11136 && expr
->ref
== NULL
)
11138 if (expr
->value
.function
.isym
!= NULL
)
11141 if (expr
->value
.function
.esym
!= NULL
)
11143 func_ifc
= expr
->value
.function
.esym
;
11146 gcc_assert (expr
->symtree
);
11147 func_ifc
= expr
->symtree
->n
.sym
;
11151 comp
= gfc_get_proc_ptr_comp (expr
);
11152 if ((expr
->expr_type
== EXPR_PPC
|| expr
->expr_type
== EXPR_FUNCTION
)
11155 func_ifc
= comp
->ts
.interface
;
11159 if (expr
->expr_type
== EXPR_COMPCALL
)
11161 gcc_assert (!expr
->value
.compcall
.tbp
->is_generic
);
11162 func_ifc
= expr
->value
.compcall
.tbp
->u
.specific
->n
.sym
;
11169 gcc_assert (func_ifc
->attr
.function
11170 && func_ifc
->result
!= NULL
);
11171 return func_ifc
->result
->attr
.pointer
;
11175 /* Is the lhs OK for automatic reallocation? */
11178 is_scalar_reallocatable_lhs (gfc_expr
*expr
)
11182 /* An allocatable variable with no reference. */
11183 if (expr
->symtree
->n
.sym
->attr
.allocatable
11187 /* All that can be left are allocatable components. However, we do
11188 not check for allocatable components here because the expression
11189 could be an allocatable component of a pointer component. */
11190 if (expr
->symtree
->n
.sym
->ts
.type
!= BT_DERIVED
11191 && expr
->symtree
->n
.sym
->ts
.type
!= BT_CLASS
)
11194 /* Find an allocatable component ref last. */
11195 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
11196 if (ref
->type
== REF_COMPONENT
11198 && ref
->u
.c
.component
->attr
.allocatable
)
11205 /* Allocate or reallocate scalar lhs, as necessary. */
11208 alloc_scalar_allocatable_for_assignment (stmtblock_t
*block
,
11209 tree string_length
,
11217 tree size_in_bytes
;
11223 if (!expr1
|| expr1
->rank
)
11226 if (!expr2
|| expr2
->rank
)
11229 for (ref
= expr1
->ref
; ref
; ref
= ref
->next
)
11230 if (ref
->type
== REF_SUBSTRING
)
11233 realloc_lhs_warning (expr2
->ts
.type
, false, &expr2
->where
);
11235 /* Since this is a scalar lhs, we can afford to do this. That is,
11236 there is no risk of side effects being repeated. */
11237 gfc_init_se (&lse
, NULL
);
11238 lse
.want_pointer
= 1;
11239 gfc_conv_expr (&lse
, expr1
);
11241 jump_label1
= gfc_build_label_decl (NULL_TREE
);
11242 jump_label2
= gfc_build_label_decl (NULL_TREE
);
11244 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
11245 tmp
= build_int_cst (TREE_TYPE (lse
.expr
), 0);
11246 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
11248 tmp
= build3_v (COND_EXPR
, cond
,
11249 build1_v (GOTO_EXPR
, jump_label1
),
11250 build_empty_stmt (input_location
));
11251 gfc_add_expr_to_block (block
, tmp
);
11253 if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.deferred
)
11255 /* Use the rhs string length and the lhs element size. Note that 'size' is
11256 used below for the string-length comparison, only. */
11257 size
= string_length
;
11258 tmp
= TYPE_SIZE_UNIT (gfc_get_char_type (expr1
->ts
.kind
));
11259 size_in_bytes
= fold_build2_loc (input_location
, MULT_EXPR
,
11260 TREE_TYPE (tmp
), tmp
,
11261 fold_convert (TREE_TYPE (tmp
), size
));
11265 /* Otherwise use the length in bytes of the rhs. */
11266 size
= TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1
->ts
));
11267 size_in_bytes
= size
;
11270 size_in_bytes
= fold_build2_loc (input_location
, MAX_EXPR
, size_type_node
,
11271 size_in_bytes
, size_one_node
);
11273 if (gfc_caf_attr (expr1
).codimension
&& flag_coarray
== GFC_FCOARRAY_LIB
)
11275 tree caf_decl
, token
;
11277 symbol_attribute attr
;
11279 gfc_clear_attr (&attr
);
11280 gfc_init_se (&caf_se
, NULL
);
11282 caf_decl
= gfc_get_tree_for_caf_expr (expr1
);
11283 gfc_get_caf_token_offset (&caf_se
, &token
, NULL
, caf_decl
, NULL_TREE
,
11285 gfc_add_block_to_block (block
, &caf_se
.pre
);
11286 gfc_allocate_allocatable (block
, lse
.expr
, size_in_bytes
,
11287 gfc_build_addr_expr (NULL_TREE
, token
),
11288 NULL_TREE
, NULL_TREE
, NULL_TREE
, jump_label1
,
11291 else if (expr1
->ts
.type
== BT_DERIVED
&& expr1
->ts
.u
.derived
->attr
.alloc_comp
)
11293 tmp
= build_call_expr_loc (input_location
,
11294 builtin_decl_explicit (BUILT_IN_CALLOC
),
11295 2, build_one_cst (size_type_node
),
11297 tmp
= fold_convert (TREE_TYPE (lse
.expr
), tmp
);
11298 gfc_add_modify (block
, lse
.expr
, tmp
);
11302 tmp
= build_call_expr_loc (input_location
,
11303 builtin_decl_explicit (BUILT_IN_MALLOC
),
11305 tmp
= fold_convert (TREE_TYPE (lse
.expr
), tmp
);
11306 gfc_add_modify (block
, lse
.expr
, tmp
);
11309 if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.deferred
)
11311 /* Deferred characters need checking for lhs and rhs string
11312 length. Other deferred parameter variables will have to
11314 tmp
= build1_v (GOTO_EXPR
, jump_label2
);
11315 gfc_add_expr_to_block (block
, tmp
);
11317 tmp
= build1_v (LABEL_EXPR
, jump_label1
);
11318 gfc_add_expr_to_block (block
, tmp
);
11320 /* For a deferred length character, reallocate if lengths of lhs and
11321 rhs are different. */
11322 if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.deferred
)
11324 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
11326 fold_convert (TREE_TYPE (lse
.string_length
),
11328 /* Jump past the realloc if the lengths are the same. */
11329 tmp
= build3_v (COND_EXPR
, cond
,
11330 build1_v (GOTO_EXPR
, jump_label2
),
11331 build_empty_stmt (input_location
));
11332 gfc_add_expr_to_block (block
, tmp
);
11333 tmp
= build_call_expr_loc (input_location
,
11334 builtin_decl_explicit (BUILT_IN_REALLOC
),
11335 2, fold_convert (pvoid_type_node
, lse
.expr
),
11337 tmp
= fold_convert (TREE_TYPE (lse
.expr
), tmp
);
11338 gfc_add_modify (block
, lse
.expr
, tmp
);
11339 tmp
= build1_v (LABEL_EXPR
, jump_label2
);
11340 gfc_add_expr_to_block (block
, tmp
);
11342 /* Update the lhs character length. */
11343 size
= string_length
;
11344 gfc_add_modify (block
, lse
.string_length
,
11345 fold_convert (TREE_TYPE (lse
.string_length
), size
));
11349 /* Check for assignments of the type
11353 to make sure we do not check for reallocation unneccessarily. */
11357 is_runtime_conformable (gfc_expr
*expr1
, gfc_expr
*expr2
)
11359 gfc_actual_arglist
*a
;
11362 switch (expr2
->expr_type
)
11364 case EXPR_VARIABLE
:
11365 return gfc_dep_compare_expr (expr1
, expr2
) == 0;
11367 case EXPR_FUNCTION
:
11368 if (expr2
->value
.function
.esym
11369 && expr2
->value
.function
.esym
->attr
.elemental
)
11371 for (a
= expr2
->value
.function
.actual
; a
!= NULL
; a
= a
->next
)
11374 if (e1
&& e1
->rank
> 0 && !is_runtime_conformable (expr1
, e1
))
11379 else if (expr2
->value
.function
.isym
11380 && expr2
->value
.function
.isym
->elemental
)
11382 for (a
= expr2
->value
.function
.actual
; a
!= NULL
; a
= a
->next
)
11385 if (e1
&& e1
->rank
> 0 && !is_runtime_conformable (expr1
, e1
))
11394 switch (expr2
->value
.op
.op
)
11396 case INTRINSIC_NOT
:
11397 case INTRINSIC_UPLUS
:
11398 case INTRINSIC_UMINUS
:
11399 case INTRINSIC_PARENTHESES
:
11400 return is_runtime_conformable (expr1
, expr2
->value
.op
.op1
);
11402 case INTRINSIC_PLUS
:
11403 case INTRINSIC_MINUS
:
11404 case INTRINSIC_TIMES
:
11405 case INTRINSIC_DIVIDE
:
11406 case INTRINSIC_POWER
:
11407 case INTRINSIC_AND
:
11409 case INTRINSIC_EQV
:
11410 case INTRINSIC_NEQV
:
11417 case INTRINSIC_EQ_OS
:
11418 case INTRINSIC_NE_OS
:
11419 case INTRINSIC_GT_OS
:
11420 case INTRINSIC_GE_OS
:
11421 case INTRINSIC_LT_OS
:
11422 case INTRINSIC_LE_OS
:
11424 e1
= expr2
->value
.op
.op1
;
11425 e2
= expr2
->value
.op
.op2
;
11427 if (e1
->rank
== 0 && e2
->rank
> 0)
11428 return is_runtime_conformable (expr1
, e2
);
11429 else if (e1
->rank
> 0 && e2
->rank
== 0)
11430 return is_runtime_conformable (expr1
, e1
);
11431 else if (e1
->rank
> 0 && e2
->rank
> 0)
11432 return is_runtime_conformable (expr1
, e1
)
11433 && is_runtime_conformable (expr1
, e2
);
11451 trans_class_assignment (stmtblock_t
*block
, gfc_expr
*lhs
, gfc_expr
*rhs
,
11452 gfc_se
*lse
, gfc_se
*rse
, bool use_vptr_copy
,
11453 bool class_realloc
)
11455 tree tmp
, fcn
, stdcopy
, to_len
, from_len
, vptr
, old_vptr
;
11456 vec
<tree
, va_gc
> *args
= NULL
;
11458 /* Store the old vptr so that dynamic types can be compared for
11459 reallocation to occur or not. */
11463 if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp
)))
11464 tmp
= gfc_get_class_from_expr (tmp
);
11467 vptr
= trans_class_vptr_len_assignment (block
, lhs
, rhs
, rse
, &to_len
,
11470 /* Generate (re)allocation of the lhs. */
11473 stmtblock_t alloc
, re_alloc
;
11474 tree class_han
, re
, size
;
11476 if (tmp
&& GFC_CLASS_TYPE_P (TREE_TYPE (tmp
)))
11477 old_vptr
= gfc_evaluate_now (gfc_class_vptr_get (tmp
), block
);
11479 old_vptr
= build_int_cst (TREE_TYPE (vptr
), 0);
11481 size
= gfc_vptr_size_get (vptr
);
11482 class_han
= GFC_CLASS_TYPE_P (TREE_TYPE (lse
->expr
))
11483 ? gfc_class_data_get (lse
->expr
) : lse
->expr
;
11485 if (!POINTER_TYPE_P (TREE_TYPE (class_han
)))
11486 class_han
= gfc_build_addr_expr (NULL_TREE
, class_han
);
11488 /* Allocate block. */
11489 gfc_init_block (&alloc
);
11490 gfc_allocate_using_malloc (&alloc
, class_han
, size
, NULL_TREE
);
11492 /* Reallocate if dynamic types are different. */
11493 gfc_init_block (&re_alloc
);
11494 re
= build_call_expr_loc (input_location
,
11495 builtin_decl_explicit (BUILT_IN_REALLOC
), 2,
11496 fold_convert (pvoid_type_node
, class_han
),
11498 tmp
= fold_build2_loc (input_location
, NE_EXPR
,
11499 logical_type_node
, vptr
, old_vptr
);
11500 re
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
11501 tmp
, re
, build_empty_stmt (input_location
));
11502 gfc_add_expr_to_block (&re_alloc
, re
);
11504 /* Allocate if _data is NULL, reallocate otherwise. */
11505 tmp
= fold_build2_loc (input_location
, EQ_EXPR
,
11506 logical_type_node
, class_han
,
11507 build_int_cst (prvoid_type_node
, 0));
11508 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
11510 PRED_FORTRAN_FAIL_ALLOC
),
11511 gfc_finish_block (&alloc
),
11512 gfc_finish_block (&re_alloc
));
11513 gfc_add_expr_to_block (&lse
->pre
, tmp
);
11516 fcn
= gfc_vptr_copy_get (vptr
);
11518 tmp
= GFC_CLASS_TYPE_P (TREE_TYPE (rse
->expr
))
11519 ? gfc_class_data_get (rse
->expr
) : rse
->expr
;
11522 if (!POINTER_TYPE_P (TREE_TYPE (tmp
))
11523 || INDIRECT_REF_P (tmp
)
11524 || (rhs
->ts
.type
== BT_DERIVED
11525 && rhs
->ts
.u
.derived
->attr
.unlimited_polymorphic
11526 && !rhs
->ts
.u
.derived
->attr
.pointer
11527 && !rhs
->ts
.u
.derived
->attr
.allocatable
)
11528 || (UNLIMITED_POLY (rhs
)
11529 && !CLASS_DATA (rhs
)->attr
.pointer
11530 && !CLASS_DATA (rhs
)->attr
.allocatable
))
11531 vec_safe_push (args
, gfc_build_addr_expr (NULL_TREE
, tmp
));
11533 vec_safe_push (args
, tmp
);
11534 tmp
= GFC_CLASS_TYPE_P (TREE_TYPE (lse
->expr
))
11535 ? gfc_class_data_get (lse
->expr
) : lse
->expr
;
11536 if (!POINTER_TYPE_P (TREE_TYPE (tmp
))
11537 || INDIRECT_REF_P (tmp
)
11538 || (lhs
->ts
.type
== BT_DERIVED
11539 && lhs
->ts
.u
.derived
->attr
.unlimited_polymorphic
11540 && !lhs
->ts
.u
.derived
->attr
.pointer
11541 && !lhs
->ts
.u
.derived
->attr
.allocatable
)
11542 || (UNLIMITED_POLY (lhs
)
11543 && !CLASS_DATA (lhs
)->attr
.pointer
11544 && !CLASS_DATA (lhs
)->attr
.allocatable
))
11545 vec_safe_push (args
, gfc_build_addr_expr (NULL_TREE
, tmp
));
11547 vec_safe_push (args
, tmp
);
11549 stdcopy
= build_call_vec (TREE_TYPE (TREE_TYPE (fcn
)), fcn
, args
);
11551 if (to_len
!= NULL_TREE
&& !integer_zerop (from_len
))
11554 vec_safe_push (args
, from_len
);
11555 vec_safe_push (args
, to_len
);
11556 extcopy
= build_call_vec (TREE_TYPE (TREE_TYPE (fcn
)), fcn
, args
);
11558 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
11559 logical_type_node
, from_len
,
11560 build_zero_cst (TREE_TYPE (from_len
)));
11561 return fold_build3_loc (input_location
, COND_EXPR
,
11562 void_type_node
, tmp
,
11570 tree rhst
= GFC_CLASS_TYPE_P (TREE_TYPE (lse
->expr
))
11571 ? gfc_class_data_get (lse
->expr
) : lse
->expr
;
11572 stmtblock_t tblock
;
11573 gfc_init_block (&tblock
);
11574 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
11575 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
11576 if (!POINTER_TYPE_P (TREE_TYPE (rhst
)))
11577 rhst
= gfc_build_addr_expr (NULL_TREE
, rhst
);
11578 /* When coming from a ptr_copy lhs and rhs are swapped. */
11579 gfc_add_modify_loc (input_location
, &tblock
, rhst
,
11580 fold_convert (TREE_TYPE (rhst
), tmp
));
11581 return gfc_finish_block (&tblock
);
11585 /* Subroutine of gfc_trans_assignment that actually scalarizes the
11586 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11587 init_flag indicates initialization expressions and dealloc that no
11588 deallocate prior assignment is needed (if in doubt, set true).
11589 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11590 routine instead of a pointer assignment. Alias resolution is only done,
11591 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11592 where it is known, that newly allocated memory on the lhs can never be
11593 an alias of the rhs. */
11596 gfc_trans_assignment_1 (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
,
11597 bool dealloc
, bool use_vptr_copy
, bool may_alias
)
11602 gfc_ss
*lss_section
;
11609 bool scalar_to_array
;
11610 tree string_length
;
11612 bool maybe_workshare
= false, lhs_refs_comp
= false, rhs_refs_comp
= false;
11613 symbol_attribute lhs_caf_attr
, rhs_caf_attr
, lhs_attr
;
11614 bool is_poly_assign
;
11617 /* Assignment of the form lhs = rhs. */
11618 gfc_start_block (&block
);
11620 gfc_init_se (&lse
, NULL
);
11621 gfc_init_se (&rse
, NULL
);
11623 /* Walk the lhs. */
11624 lss
= gfc_walk_expr (expr1
);
11625 if (gfc_is_reallocatable_lhs (expr1
))
11627 lss
->no_bounds_check
= 1;
11628 if (!(expr2
->expr_type
== EXPR_FUNCTION
11629 && expr2
->value
.function
.isym
!= NULL
11630 && !(expr2
->value
.function
.isym
->elemental
11631 || expr2
->value
.function
.isym
->conversion
)))
11632 lss
->is_alloc_lhs
= 1;
11635 lss
->no_bounds_check
= expr1
->no_bounds_check
;
11639 if ((expr1
->ts
.type
== BT_DERIVED
)
11640 && (gfc_is_class_array_function (expr2
)
11641 || gfc_is_alloc_class_scalar_function (expr2
)))
11642 expr2
->must_finalize
= 1;
11644 /* Checking whether a class assignment is desired is quite complicated and
11645 needed at two locations, so do it once only before the information is
11647 lhs_attr
= gfc_expr_attr (expr1
);
11648 is_poly_assign
= (use_vptr_copy
|| lhs_attr
.pointer
11649 || (lhs_attr
.allocatable
&& !lhs_attr
.dimension
))
11650 && (expr1
->ts
.type
== BT_CLASS
11651 || gfc_is_class_array_ref (expr1
, NULL
)
11652 || gfc_is_class_scalar_expr (expr1
)
11653 || gfc_is_class_array_ref (expr2
, NULL
)
11654 || gfc_is_class_scalar_expr (expr2
))
11655 && lhs_attr
.flavor
!= FL_PROCEDURE
;
11657 realloc_flag
= flag_realloc_lhs
11658 && gfc_is_reallocatable_lhs (expr1
)
11660 && !is_runtime_conformable (expr1
, expr2
);
11662 /* Only analyze the expressions for coarray properties, when in coarray-lib
11664 if (flag_coarray
== GFC_FCOARRAY_LIB
)
11666 lhs_caf_attr
= gfc_caf_attr (expr1
, false, &lhs_refs_comp
);
11667 rhs_caf_attr
= gfc_caf_attr (expr2
, false, &rhs_refs_comp
);
11670 if (lss
!= gfc_ss_terminator
)
11672 /* The assignment needs scalarization. */
11675 /* Find a non-scalar SS from the lhs. */
11676 while (lss_section
!= gfc_ss_terminator
11677 && lss_section
->info
->type
!= GFC_SS_SECTION
)
11678 lss_section
= lss_section
->next
;
11680 gcc_assert (lss_section
!= gfc_ss_terminator
);
11682 /* Initialize the scalarizer. */
11683 gfc_init_loopinfo (&loop
);
11685 /* Walk the rhs. */
11686 rss
= gfc_walk_expr (expr2
);
11687 if (rss
== gfc_ss_terminator
)
11688 /* The rhs is scalar. Add a ss for the expression. */
11689 rss
= gfc_get_scalar_ss (gfc_ss_terminator
, expr2
);
11690 /* When doing a class assign, then the handle to the rhs needs to be a
11691 pointer to allow for polymorphism. */
11692 if (is_poly_assign
&& expr2
->rank
== 0 && !UNLIMITED_POLY (expr2
))
11693 rss
->info
->type
= GFC_SS_REFERENCE
;
11695 rss
->no_bounds_check
= expr2
->no_bounds_check
;
11696 /* Associate the SS with the loop. */
11697 gfc_add_ss_to_loop (&loop
, lss
);
11698 gfc_add_ss_to_loop (&loop
, rss
);
11700 /* Calculate the bounds of the scalarization. */
11701 gfc_conv_ss_startstride (&loop
);
11702 /* Enable loop reversal. */
11703 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
11704 loop
.reverse
[n
] = GFC_ENABLE_REVERSE
;
11705 /* Resolve any data dependencies in the statement. */
11707 gfc_conv_resolve_dependencies (&loop
, lss
, rss
);
11708 /* Setup the scalarizing loops. */
11709 gfc_conv_loop_setup (&loop
, &expr2
->where
);
11711 /* Setup the gfc_se structures. */
11712 gfc_copy_loopinfo_to_se (&lse
, &loop
);
11713 gfc_copy_loopinfo_to_se (&rse
, &loop
);
11716 gfc_mark_ss_chain_used (rss
, 1);
11717 if (loop
.temp_ss
== NULL
)
11720 gfc_mark_ss_chain_used (lss
, 1);
11724 lse
.ss
= loop
.temp_ss
;
11725 gfc_mark_ss_chain_used (lss
, 3);
11726 gfc_mark_ss_chain_used (loop
.temp_ss
, 3);
11729 /* Allow the scalarizer to workshare array assignments. */
11730 if ((ompws_flags
& (OMPWS_WORKSHARE_FLAG
| OMPWS_SCALARIZER_BODY
))
11731 == OMPWS_WORKSHARE_FLAG
11732 && loop
.temp_ss
== NULL
)
11734 maybe_workshare
= true;
11735 ompws_flags
|= OMPWS_SCALARIZER_WS
| OMPWS_SCALARIZER_BODY
;
11738 /* Start the scalarized loop body. */
11739 gfc_start_scalarized_body (&loop
, &body
);
11742 gfc_init_block (&body
);
11744 l_is_temp
= (lss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
);
11746 /* Translate the expression. */
11747 rse
.want_coarray
= flag_coarray
== GFC_FCOARRAY_LIB
&& init_flag
11748 && lhs_caf_attr
.codimension
;
11749 gfc_conv_expr (&rse
, expr2
);
11751 /* Deal with the case of a scalar class function assigned to a derived type. */
11752 if (gfc_is_alloc_class_scalar_function (expr2
)
11753 && expr1
->ts
.type
== BT_DERIVED
)
11755 rse
.expr
= gfc_class_data_get (rse
.expr
);
11756 rse
.expr
= build_fold_indirect_ref_loc (input_location
, rse
.expr
);
11759 /* Stabilize a string length for temporaries. */
11760 if (expr2
->ts
.type
== BT_CHARACTER
&& !expr1
->ts
.deferred
11761 && !(VAR_P (rse
.string_length
)
11762 || TREE_CODE (rse
.string_length
) == PARM_DECL
11763 || TREE_CODE (rse
.string_length
) == INDIRECT_REF
))
11764 string_length
= gfc_evaluate_now (rse
.string_length
, &rse
.pre
);
11765 else if (expr2
->ts
.type
== BT_CHARACTER
)
11767 if (expr1
->ts
.deferred
11768 && gfc_expr_attr (expr1
).allocatable
11769 && gfc_check_dependency (expr1
, expr2
, true))
11770 rse
.string_length
=
11771 gfc_evaluate_now_function_scope (rse
.string_length
, &rse
.pre
);
11772 string_length
= rse
.string_length
;
11775 string_length
= NULL_TREE
;
11779 gfc_conv_tmp_array_ref (&lse
);
11780 if (expr2
->ts
.type
== BT_CHARACTER
)
11781 lse
.string_length
= string_length
;
11785 gfc_conv_expr (&lse
, expr1
);
11786 if (gfc_option
.rtcheck
& GFC_RTCHECK_MEM
11788 && gfc_expr_attr (expr1
).allocatable
11795 tmp
= INDIRECT_REF_P (lse
.expr
)
11796 ? gfc_build_addr_expr (NULL_TREE
, lse
.expr
) : lse
.expr
;
11799 /* We should only get array references here. */
11800 gcc_assert (TREE_CODE (tmp
) == POINTER_PLUS_EXPR
11801 || TREE_CODE (tmp
) == ARRAY_REF
);
11803 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11804 or the array itself(ARRAY_REF). */
11805 tmp
= TREE_OPERAND (tmp
, 0);
11807 /* Provide the address of the array. */
11808 if (TREE_CODE (lse
.expr
) == ARRAY_REF
)
11809 tmp
= gfc_build_addr_expr (NULL_TREE
, tmp
);
11811 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
11812 tmp
, build_int_cst (TREE_TYPE (tmp
), 0));
11813 msg
= _("Assignment of scalar to unallocated array");
11814 gfc_trans_runtime_check (true, false, cond
, &loop
.pre
,
11815 &expr1
->where
, msg
);
11818 /* Deallocate the lhs parameterized components if required. */
11819 if (dealloc
&& expr2
->expr_type
== EXPR_FUNCTION
11820 && !expr1
->symtree
->n
.sym
->attr
.associate_var
)
11822 if (expr1
->ts
.type
== BT_DERIVED
11823 && expr1
->ts
.u
.derived
11824 && expr1
->ts
.u
.derived
->attr
.pdt_type
)
11826 tmp
= gfc_deallocate_pdt_comp (expr1
->ts
.u
.derived
, lse
.expr
,
11828 gfc_add_expr_to_block (&lse
.pre
, tmp
);
11830 else if (expr1
->ts
.type
== BT_CLASS
11831 && CLASS_DATA (expr1
)->ts
.u
.derived
11832 && CLASS_DATA (expr1
)->ts
.u
.derived
->attr
.pdt_type
)
11834 tmp
= gfc_class_data_get (lse
.expr
);
11835 tmp
= gfc_deallocate_pdt_comp (CLASS_DATA (expr1
)->ts
.u
.derived
,
11837 gfc_add_expr_to_block (&lse
.pre
, tmp
);
11842 /* Assignments of scalar derived types with allocatable components
11843 to arrays must be done with a deep copy and the rhs temporary
11844 must have its components deallocated afterwards. */
11845 scalar_to_array
= (expr2
->ts
.type
== BT_DERIVED
11846 && expr2
->ts
.u
.derived
->attr
.alloc_comp
11847 && !gfc_expr_is_variable (expr2
)
11848 && expr1
->rank
&& !expr2
->rank
);
11849 scalar_to_array
|= (expr1
->ts
.type
== BT_DERIVED
11851 && expr1
->ts
.u
.derived
->attr
.alloc_comp
11852 && gfc_is_alloc_class_scalar_function (expr2
));
11853 if (scalar_to_array
&& dealloc
)
11855 tmp
= gfc_deallocate_alloc_comp_no_caf (expr2
->ts
.u
.derived
, rse
.expr
, 0);
11856 gfc_prepend_expr_to_block (&loop
.post
, tmp
);
11859 /* When assigning a character function result to a deferred-length variable,
11860 the function call must happen before the (re)allocation of the lhs -
11861 otherwise the character length of the result is not known.
11862 NOTE 1: This relies on having the exact dependence of the length type
11863 parameter available to the caller; gfortran saves it in the .mod files.
11864 NOTE 2: Vector array references generate an index temporary that must
11865 not go outside the loop. Otherwise, variables should not generate
11867 NOTE 3: The concatenation operation generates a temporary pointer,
11868 whose allocation must go to the innermost loop.
11869 NOTE 4: Elemental functions may generate a temporary, too. */
11870 if (flag_realloc_lhs
11871 && expr2
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.deferred
11872 && !(lss
!= gfc_ss_terminator
11873 && rss
!= gfc_ss_terminator
11874 && ((expr2
->expr_type
== EXPR_VARIABLE
&& expr2
->rank
)
11875 || (expr2
->expr_type
== EXPR_FUNCTION
11876 && expr2
->value
.function
.esym
!= NULL
11877 && expr2
->value
.function
.esym
->attr
.elemental
)
11878 || (expr2
->expr_type
== EXPR_FUNCTION
11879 && expr2
->value
.function
.isym
!= NULL
11880 && expr2
->value
.function
.isym
->elemental
)
11881 || (expr2
->expr_type
== EXPR_OP
11882 && expr2
->value
.op
.op
== INTRINSIC_CONCAT
))))
11883 gfc_add_block_to_block (&block
, &rse
.pre
);
11885 /* Nullify the allocatable components corresponding to those of the lhs
11886 derived type, so that the finalization of the function result does not
11887 affect the lhs of the assignment. Prepend is used to ensure that the
11888 nullification occurs before the call to the finalizer. In the case of
11889 a scalar to array assignment, this is done in gfc_trans_scalar_assign
11890 as part of the deep copy. */
11891 if (!scalar_to_array
&& expr1
->ts
.type
== BT_DERIVED
11892 && (gfc_is_class_array_function (expr2
)
11893 || gfc_is_alloc_class_scalar_function (expr2
)))
11895 tmp
= gfc_nullify_alloc_comp (expr1
->ts
.u
.derived
, rse
.expr
, 0);
11896 gfc_prepend_expr_to_block (&rse
.post
, tmp
);
11897 if (lss
!= gfc_ss_terminator
&& rss
== gfc_ss_terminator
)
11898 gfc_add_block_to_block (&loop
.post
, &rse
.post
);
11903 if (is_poly_assign
)
11905 tmp
= trans_class_assignment (&body
, expr1
, expr2
, &lse
, &rse
,
11906 use_vptr_copy
|| (lhs_attr
.allocatable
11907 && !lhs_attr
.dimension
),
11908 !realloc_flag
&& flag_realloc_lhs
11909 && !lhs_attr
.pointer
);
11910 if (expr2
->expr_type
== EXPR_FUNCTION
11911 && expr2
->ts
.type
== BT_DERIVED
11912 && expr2
->ts
.u
.derived
->attr
.alloc_comp
)
11914 tree tmp2
= gfc_deallocate_alloc_comp (expr2
->ts
.u
.derived
,
11915 rse
.expr
, expr2
->rank
);
11916 if (lss
== gfc_ss_terminator
)
11917 gfc_add_expr_to_block (&rse
.post
, tmp2
);
11919 gfc_add_expr_to_block (&loop
.post
, tmp2
);
11922 else if (flag_coarray
== GFC_FCOARRAY_LIB
11923 && lhs_caf_attr
.codimension
&& rhs_caf_attr
.codimension
11924 && ((lhs_caf_attr
.allocatable
&& lhs_refs_comp
)
11925 || (rhs_caf_attr
.allocatable
&& rhs_refs_comp
)))
11927 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11928 allocatable component, because those need to be accessed via the
11929 caf-runtime. No need to check for coindexes here, because resolve
11930 has rewritten those already. */
11932 gfc_actual_arglist a1
, a2
;
11933 /* Clear the structures to prevent accessing garbage. */
11934 memset (&code
, '\0', sizeof (gfc_code
));
11935 memset (&a1
, '\0', sizeof (gfc_actual_arglist
));
11936 memset (&a2
, '\0', sizeof (gfc_actual_arglist
));
11941 code
.ext
.actual
= &a1
;
11942 code
.resolved_isym
= gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND
);
11943 tmp
= gfc_conv_intrinsic_subroutine (&code
);
11945 else if (!is_poly_assign
&& expr2
->must_finalize
11946 && expr1
->ts
.type
== BT_CLASS
11947 && expr2
->ts
.type
== BT_CLASS
)
11949 /* This case comes about when the scalarizer provides array element
11950 references. Use the vptr copy function, since this does a deep
11951 copy of allocatable components, without which the finalizer call
11952 will deallocate the components. */
11953 tmp
= gfc_get_vptr_from_expr (rse
.expr
);
11954 if (tmp
!= NULL_TREE
)
11956 tree fcn
= gfc_vptr_copy_get (tmp
);
11957 if (POINTER_TYPE_P (TREE_TYPE (fcn
)))
11958 fcn
= build_fold_indirect_ref_loc (input_location
, fcn
);
11959 tmp
= build_call_expr_loc (input_location
,
11961 gfc_build_addr_expr (NULL
, rse
.expr
),
11962 gfc_build_addr_expr (NULL
, lse
.expr
));
11966 /* If nothing else works, do it the old fashioned way! */
11967 if (tmp
== NULL_TREE
)
11968 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
11969 gfc_expr_is_variable (expr2
)
11971 || expr2
->expr_type
== EXPR_ARRAY
,
11972 !(l_is_temp
|| init_flag
) && dealloc
,
11973 expr1
->symtree
->n
.sym
->attr
.codimension
);
11975 /* Add the pre blocks to the body. */
11976 gfc_add_block_to_block (&body
, &rse
.pre
);
11977 gfc_add_block_to_block (&body
, &lse
.pre
);
11978 gfc_add_expr_to_block (&body
, tmp
);
11979 /* Add the post blocks to the body. */
11980 gfc_add_block_to_block (&body
, &rse
.post
);
11981 gfc_add_block_to_block (&body
, &lse
.post
);
11983 if (lss
== gfc_ss_terminator
)
11985 /* F2003: Add the code for reallocation on assignment. */
11986 if (flag_realloc_lhs
&& is_scalar_reallocatable_lhs (expr1
)
11987 && !is_poly_assign
)
11988 alloc_scalar_allocatable_for_assignment (&block
, string_length
,
11991 /* Use the scalar assignment as is. */
11992 gfc_add_block_to_block (&block
, &body
);
11996 gcc_assert (lse
.ss
== gfc_ss_terminator
11997 && rse
.ss
== gfc_ss_terminator
);
12001 gfc_trans_scalarized_loop_boundary (&loop
, &body
);
12003 /* We need to copy the temporary to the actual lhs. */
12004 gfc_init_se (&lse
, NULL
);
12005 gfc_init_se (&rse
, NULL
);
12006 gfc_copy_loopinfo_to_se (&lse
, &loop
);
12007 gfc_copy_loopinfo_to_se (&rse
, &loop
);
12009 rse
.ss
= loop
.temp_ss
;
12012 gfc_conv_tmp_array_ref (&rse
);
12013 gfc_conv_expr (&lse
, expr1
);
12015 gcc_assert (lse
.ss
== gfc_ss_terminator
12016 && rse
.ss
== gfc_ss_terminator
);
12018 if (expr2
->ts
.type
== BT_CHARACTER
)
12019 rse
.string_length
= string_length
;
12021 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
12023 gfc_add_expr_to_block (&body
, tmp
);
12026 /* F2003: Allocate or reallocate lhs of allocatable array. */
12029 realloc_lhs_warning (expr1
->ts
.type
, true, &expr1
->where
);
12030 ompws_flags
&= ~OMPWS_SCALARIZER_WS
;
12031 tmp
= gfc_alloc_allocatable_for_assignment (&loop
, expr1
, expr2
);
12032 if (tmp
!= NULL_TREE
)
12033 gfc_add_expr_to_block (&loop
.code
[expr1
->rank
- 1], tmp
);
12036 if (maybe_workshare
)
12037 ompws_flags
&= ~OMPWS_SCALARIZER_BODY
;
12039 /* Generate the copying loops. */
12040 gfc_trans_scalarizing_loops (&loop
, &body
);
12042 /* Wrap the whole thing up. */
12043 gfc_add_block_to_block (&block
, &loop
.pre
);
12044 gfc_add_block_to_block (&block
, &loop
.post
);
12046 gfc_cleanup_loop (&loop
);
12049 return gfc_finish_block (&block
);
12053 /* Check whether EXPR is a copyable array. */
12056 copyable_array_p (gfc_expr
* expr
)
12058 if (expr
->expr_type
!= EXPR_VARIABLE
)
12061 /* First check it's an array. */
12062 if (expr
->rank
< 1 || !expr
->ref
|| expr
->ref
->next
)
12065 if (!gfc_full_array_ref_p (expr
->ref
, NULL
))
12068 /* Next check that it's of a simple enough type. */
12069 switch (expr
->ts
.type
)
12081 return !expr
->ts
.u
.derived
->attr
.alloc_comp
;
12090 /* Translate an assignment. */
12093 gfc_trans_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
,
12094 bool dealloc
, bool use_vptr_copy
, bool may_alias
)
12098 /* Special case a single function returning an array. */
12099 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->rank
> 0)
12101 tmp
= gfc_trans_arrayfunc_assign (expr1
, expr2
);
12106 /* Special case assigning an array to zero. */
12107 if (copyable_array_p (expr1
)
12108 && is_zero_initializer_p (expr2
))
12110 tmp
= gfc_trans_zero_assign (expr1
);
12115 /* Special case copying one array to another. */
12116 if (copyable_array_p (expr1
)
12117 && copyable_array_p (expr2
)
12118 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
)
12119 && !gfc_check_dependency (expr1
, expr2
, 0))
12121 tmp
= gfc_trans_array_copy (expr1
, expr2
);
12126 /* Special case initializing an array from a constant array constructor. */
12127 if (copyable_array_p (expr1
)
12128 && expr2
->expr_type
== EXPR_ARRAY
12129 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
))
12131 tmp
= gfc_trans_array_constructor_copy (expr1
, expr2
);
12136 if (UNLIMITED_POLY (expr1
) && expr1
->rank
)
12137 use_vptr_copy
= true;
12139 /* Fallback to the scalarizer to generate explicit loops. */
12140 return gfc_trans_assignment_1 (expr1
, expr2
, init_flag
, dealloc
,
12141 use_vptr_copy
, may_alias
);
12145 gfc_trans_init_assign (gfc_code
* code
)
12147 return gfc_trans_assignment (code
->expr1
, code
->expr2
, true, false, true);
12151 gfc_trans_assign (gfc_code
* code
)
12153 return gfc_trans_assignment (code
->expr1
, code
->expr2
, false, true);
12156 /* Generate a simple loop for internal use of the form
12157 for (var = begin; var <cond> end; var += step)
12160 gfc_simple_for_loop (stmtblock_t
*block
, tree var
, tree begin
, tree end
,
12161 enum tree_code cond
, tree step
, tree body
)
12166 gfc_add_modify (block
, var
, begin
);
12168 /* Loop: for (var = begin; var <cond> end; var += step). */
12169 tree label_loop
= gfc_build_label_decl (NULL_TREE
);
12170 tree label_cond
= gfc_build_label_decl (NULL_TREE
);
12171 TREE_USED (label_loop
) = 1;
12172 TREE_USED (label_cond
) = 1;
12174 gfc_add_expr_to_block (block
, build1_v (GOTO_EXPR
, label_cond
));
12175 gfc_add_expr_to_block (block
, build1_v (LABEL_EXPR
, label_loop
));
12178 gfc_add_expr_to_block (block
, body
);
12180 /* End of loop body. */
12181 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (var
), var
, step
);
12182 gfc_add_modify (block
, var
, tmp
);
12183 gfc_add_expr_to_block (block
, build1_v (LABEL_EXPR
, label_cond
));
12184 tmp
= fold_build2_loc (input_location
, cond
, boolean_type_node
, var
, end
);
12185 tmp
= build3_v (COND_EXPR
, tmp
, build1_v (GOTO_EXPR
, label_loop
),
12186 build_empty_stmt (input_location
));
12187 gfc_add_expr_to_block (block
, tmp
);