trans-expr.cc revision 1.1 1 1.1 mrg /* Expression translation
2 1.1 mrg Copyright (C) 2002-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Paul Brook <paul (at) nowt.org>
4 1.1 mrg and Steven Bosscher <s.bosscher (at) student.tudelft.nl>
5 1.1 mrg
6 1.1 mrg This file is part of GCC.
7 1.1 mrg
8 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
9 1.1 mrg the terms of the GNU General Public License as published by the Free
10 1.1 mrg Software Foundation; either version 3, or (at your option) any later
11 1.1 mrg version.
12 1.1 mrg
13 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 1.1 mrg for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU General Public License
19 1.1 mrg along with GCC; see the file COPYING3. If not see
20 1.1 mrg <http://www.gnu.org/licenses/>. */
21 1.1 mrg
22 1.1 mrg /* trans-expr.cc-- generate GENERIC trees for gfc_expr. */
23 1.1 mrg
24 1.1 mrg #include "config.h"
25 1.1 mrg #include "system.h"
26 1.1 mrg #include "coretypes.h"
27 1.1 mrg #include "options.h"
28 1.1 mrg #include "tree.h"
29 1.1 mrg #include "gfortran.h"
30 1.1 mrg #include "trans.h"
31 1.1 mrg #include "stringpool.h"
32 1.1 mrg #include "diagnostic-core.h" /* For fatal_error. */
33 1.1 mrg #include "fold-const.h"
34 1.1 mrg #include "langhooks.h"
35 1.1 mrg #include "arith.h"
36 1.1 mrg #include "constructor.h"
37 1.1 mrg #include "trans-const.h"
38 1.1 mrg #include "trans-types.h"
39 1.1 mrg #include "trans-array.h"
40 1.1 mrg /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 1.1 mrg #include "trans-stmt.h"
42 1.1 mrg #include "dependency.h"
43 1.1 mrg #include "gimplify.h"
44 1.1 mrg #include "tm.h" /* For CHAR_TYPE_SIZE. */
45 1.1 mrg
46 1.1 mrg
47 1.1 mrg /* Calculate the number of characters in a string. */
48 1.1 mrg
49 1.1 mrg static tree
50 1.1 mrg gfc_get_character_len (tree type)
51 1.1 mrg {
52 1.1 mrg tree len;
53 1.1 mrg
54 1.1 mrg gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
55 1.1 mrg && TYPE_STRING_FLAG (type));
56 1.1 mrg
57 1.1 mrg len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
58 1.1 mrg len = (len) ? (len) : (integer_zero_node);
59 1.1 mrg return fold_convert (gfc_charlen_type_node, len);
60 1.1 mrg }
61 1.1 mrg
62 1.1 mrg
63 1.1 mrg
64 1.1 mrg /* Calculate the number of bytes in a string. */
65 1.1 mrg
66 1.1 mrg tree
67 1.1 mrg gfc_get_character_len_in_bytes (tree type)
68 1.1 mrg {
69 1.1 mrg tree tmp, len;
70 1.1 mrg
71 1.1 mrg gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
72 1.1 mrg && TYPE_STRING_FLAG (type));
73 1.1 mrg
74 1.1 mrg tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
75 1.1 mrg tmp = (tmp && !integer_zerop (tmp))
76 1.1 mrg ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
77 1.1 mrg len = gfc_get_character_len (type);
78 1.1 mrg if (tmp && len && !integer_zerop (len))
79 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR,
80 1.1 mrg gfc_charlen_type_node, len, tmp);
81 1.1 mrg return len;
82 1.1 mrg }
83 1.1 mrg
84 1.1 mrg
85 1.1 mrg /* Convert a scalar to an array descriptor. To be used for assumed-rank
86 1.1 mrg arrays. */
87 1.1 mrg
88 1.1 mrg static tree
89 1.1 mrg get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
90 1.1 mrg {
91 1.1 mrg enum gfc_array_kind akind;
92 1.1 mrg
93 1.1 mrg if (attr.pointer)
94 1.1 mrg akind = GFC_ARRAY_POINTER_CONT;
95 1.1 mrg else if (attr.allocatable)
96 1.1 mrg akind = GFC_ARRAY_ALLOCATABLE;
97 1.1 mrg else
98 1.1 mrg akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
99 1.1 mrg
100 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (scalar)))
101 1.1 mrg scalar = TREE_TYPE (scalar);
102 1.1 mrg return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
103 1.1 mrg akind, !(attr.pointer || attr.target));
104 1.1 mrg }
105 1.1 mrg
106 1.1 mrg tree
107 1.1 mrg gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
108 1.1 mrg {
109 1.1 mrg tree desc, type, etype;
110 1.1 mrg
111 1.1 mrg type = get_scalar_to_descriptor_type (scalar, attr);
112 1.1 mrg etype = TREE_TYPE (scalar);
113 1.1 mrg desc = gfc_create_var (type, "desc");
114 1.1 mrg DECL_ARTIFICIAL (desc) = 1;
115 1.1 mrg
116 1.1 mrg if (CONSTANT_CLASS_P (scalar))
117 1.1 mrg {
118 1.1 mrg tree tmp;
119 1.1 mrg tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
120 1.1 mrg gfc_add_modify (&se->pre, tmp, scalar);
121 1.1 mrg scalar = tmp;
122 1.1 mrg }
123 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
124 1.1 mrg scalar = gfc_build_addr_expr (NULL_TREE, scalar);
125 1.1 mrg else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
126 1.1 mrg etype = TREE_TYPE (etype);
127 1.1 mrg gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
128 1.1 mrg gfc_get_dtype_rank_type (0, etype));
129 1.1 mrg gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
130 1.1 mrg gfc_conv_descriptor_span_set (&se->pre, desc,
131 1.1 mrg gfc_conv_descriptor_elem_len (desc));
132 1.1 mrg
133 1.1 mrg /* Copy pointer address back - but only if it could have changed and
134 1.1 mrg if the actual argument is a pointer and not, e.g., NULL(). */
135 1.1 mrg if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
136 1.1 mrg gfc_add_modify (&se->post, scalar,
137 1.1 mrg fold_convert (TREE_TYPE (scalar),
138 1.1 mrg gfc_conv_descriptor_data_get (desc)));
139 1.1 mrg return desc;
140 1.1 mrg }
141 1.1 mrg
142 1.1 mrg
143 1.1 mrg /* Get the coarray token from the ultimate array or component ref.
144 1.1 mrg Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
145 1.1 mrg
146 1.1 mrg tree
147 1.1 mrg gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
148 1.1 mrg {
149 1.1 mrg gfc_symbol *sym = expr->symtree->n.sym;
150 1.1 mrg bool is_coarray = sym->attr.codimension;
151 1.1 mrg gfc_expr *caf_expr = gfc_copy_expr (expr);
152 1.1 mrg gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
153 1.1 mrg
154 1.1 mrg while (ref)
155 1.1 mrg {
156 1.1 mrg if (ref->type == REF_COMPONENT
157 1.1 mrg && (ref->u.c.component->attr.allocatable
158 1.1 mrg || ref->u.c.component->attr.pointer)
159 1.1 mrg && (is_coarray || ref->u.c.component->attr.codimension))
160 1.1 mrg last_caf_ref = ref;
161 1.1 mrg ref = ref->next;
162 1.1 mrg }
163 1.1 mrg
164 1.1 mrg if (last_caf_ref == NULL)
165 1.1 mrg return NULL_TREE;
166 1.1 mrg
167 1.1 mrg tree comp = last_caf_ref->u.c.component->caf_token, caf;
168 1.1 mrg gfc_se se;
169 1.1 mrg bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
170 1.1 mrg if (comp == NULL_TREE && comp_ref)
171 1.1 mrg return NULL_TREE;
172 1.1 mrg gfc_init_se (&se, outerse);
173 1.1 mrg gfc_free_ref_list (last_caf_ref->next);
174 1.1 mrg last_caf_ref->next = NULL;
175 1.1 mrg caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
176 1.1 mrg se.want_pointer = comp_ref;
177 1.1 mrg gfc_conv_expr (&se, caf_expr);
178 1.1 mrg gfc_add_block_to_block (&outerse->pre, &se.pre);
179 1.1 mrg
180 1.1 mrg if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
181 1.1 mrg se.expr = TREE_OPERAND (se.expr, 0);
182 1.1 mrg gfc_free_expr (caf_expr);
183 1.1 mrg
184 1.1 mrg if (comp_ref)
185 1.1 mrg caf = fold_build3_loc (input_location, COMPONENT_REF,
186 1.1 mrg TREE_TYPE (comp), se.expr, comp, NULL_TREE);
187 1.1 mrg else
188 1.1 mrg caf = gfc_conv_descriptor_token (se.expr);
189 1.1 mrg return gfc_build_addr_expr (NULL_TREE, caf);
190 1.1 mrg }
191 1.1 mrg
192 1.1 mrg
193 1.1 mrg /* This is the seed for an eventual trans-class.c
194 1.1 mrg
195 1.1 mrg The following parameters should not be used directly since they might
196 1.1 mrg in future implementations. Use the corresponding APIs. */
197 1.1 mrg #define CLASS_DATA_FIELD 0
198 1.1 mrg #define CLASS_VPTR_FIELD 1
199 1.1 mrg #define CLASS_LEN_FIELD 2
200 1.1 mrg #define VTABLE_HASH_FIELD 0
201 1.1 mrg #define VTABLE_SIZE_FIELD 1
202 1.1 mrg #define VTABLE_EXTENDS_FIELD 2
203 1.1 mrg #define VTABLE_DEF_INIT_FIELD 3
204 1.1 mrg #define VTABLE_COPY_FIELD 4
205 1.1 mrg #define VTABLE_FINAL_FIELD 5
206 1.1 mrg #define VTABLE_DEALLOCATE_FIELD 6
207 1.1 mrg
208 1.1 mrg
209 1.1 mrg tree
210 1.1 mrg gfc_class_set_static_fields (tree decl, tree vptr, tree data)
211 1.1 mrg {
212 1.1 mrg tree tmp;
213 1.1 mrg tree field;
214 1.1 mrg vec<constructor_elt, va_gc> *init = NULL;
215 1.1 mrg
216 1.1 mrg field = TYPE_FIELDS (TREE_TYPE (decl));
217 1.1 mrg tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
218 1.1 mrg CONSTRUCTOR_APPEND_ELT (init, tmp, data);
219 1.1 mrg
220 1.1 mrg tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
221 1.1 mrg CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
222 1.1 mrg
223 1.1 mrg return build_constructor (TREE_TYPE (decl), init);
224 1.1 mrg }
225 1.1 mrg
226 1.1 mrg
227 1.1 mrg tree
228 1.1 mrg gfc_class_data_get (tree decl)
229 1.1 mrg {
230 1.1 mrg tree data;
231 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl)))
232 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
233 1.1 mrg data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
234 1.1 mrg CLASS_DATA_FIELD);
235 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF,
236 1.1 mrg TREE_TYPE (data), decl, data,
237 1.1 mrg NULL_TREE);
238 1.1 mrg }
239 1.1 mrg
240 1.1 mrg
241 1.1 mrg tree
242 1.1 mrg gfc_class_vptr_get (tree decl)
243 1.1 mrg {
244 1.1 mrg tree vptr;
245 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the vptr is
246 1.1 mrg then available through the saved descriptor. */
247 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
248 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl))
249 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
250 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl)))
251 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
252 1.1 mrg vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
253 1.1 mrg CLASS_VPTR_FIELD);
254 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF,
255 1.1 mrg TREE_TYPE (vptr), decl, vptr,
256 1.1 mrg NULL_TREE);
257 1.1 mrg }
258 1.1 mrg
259 1.1 mrg
260 1.1 mrg tree
261 1.1 mrg gfc_class_len_get (tree decl)
262 1.1 mrg {
263 1.1 mrg tree len;
264 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the len is
265 1.1 mrg then available through the saved descriptor. */
266 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
267 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl))
268 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
269 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl)))
270 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
271 1.1 mrg len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
272 1.1 mrg CLASS_LEN_FIELD);
273 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF,
274 1.1 mrg TREE_TYPE (len), decl, len,
275 1.1 mrg NULL_TREE);
276 1.1 mrg }
277 1.1 mrg
278 1.1 mrg
279 1.1 mrg /* Try to get the _len component of a class. When the class is not unlimited
280 1.1 mrg poly, i.e. no _len field exists, then return a zero node. */
281 1.1 mrg
282 1.1 mrg static tree
283 1.1 mrg gfc_class_len_or_zero_get (tree decl)
284 1.1 mrg {
285 1.1 mrg tree len;
286 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the vptr is
287 1.1 mrg then available through the saved descriptor. */
288 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
289 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl))
290 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
291 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl)))
292 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
293 1.1 mrg len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
294 1.1 mrg CLASS_LEN_FIELD);
295 1.1 mrg return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
296 1.1 mrg TREE_TYPE (len), decl, len,
297 1.1 mrg NULL_TREE)
298 1.1 mrg : build_zero_cst (gfc_charlen_type_node);
299 1.1 mrg }
300 1.1 mrg
301 1.1 mrg
302 1.1 mrg tree
303 1.1 mrg gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
304 1.1 mrg {
305 1.1 mrg tree tmp;
306 1.1 mrg tree tmp2;
307 1.1 mrg tree type;
308 1.1 mrg
309 1.1 mrg tmp = gfc_class_len_or_zero_get (class_expr);
310 1.1 mrg
311 1.1 mrg /* Include the len value in the element size if present. */
312 1.1 mrg if (!integer_zerop (tmp))
313 1.1 mrg {
314 1.1 mrg type = TREE_TYPE (size);
315 1.1 mrg if (block)
316 1.1 mrg {
317 1.1 mrg size = gfc_evaluate_now (size, block);
318 1.1 mrg tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
319 1.1 mrg }
320 1.1 mrg tmp2 = fold_build2_loc (input_location, MULT_EXPR,
321 1.1 mrg type, size, tmp);
322 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR,
323 1.1 mrg logical_type_node, tmp,
324 1.1 mrg build_zero_cst (type));
325 1.1 mrg size = fold_build3_loc (input_location, COND_EXPR,
326 1.1 mrg type, tmp, tmp2, size);
327 1.1 mrg }
328 1.1 mrg else
329 1.1 mrg return size;
330 1.1 mrg
331 1.1 mrg if (block)
332 1.1 mrg size = gfc_evaluate_now (size, block);
333 1.1 mrg
334 1.1 mrg return size;
335 1.1 mrg }
336 1.1 mrg
337 1.1 mrg
338 1.1 mrg /* Get the specified FIELD from the VPTR. */
339 1.1 mrg
340 1.1 mrg static tree
341 1.1 mrg vptr_field_get (tree vptr, int fieldno)
342 1.1 mrg {
343 1.1 mrg tree field;
344 1.1 mrg vptr = build_fold_indirect_ref_loc (input_location, vptr);
345 1.1 mrg field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
346 1.1 mrg fieldno);
347 1.1 mrg field = fold_build3_loc (input_location, COMPONENT_REF,
348 1.1 mrg TREE_TYPE (field), vptr, field,
349 1.1 mrg NULL_TREE);
350 1.1 mrg gcc_assert (field);
351 1.1 mrg return field;
352 1.1 mrg }
353 1.1 mrg
354 1.1 mrg
355 1.1 mrg /* Get the field from the class' vptr. */
356 1.1 mrg
357 1.1 mrg static tree
358 1.1 mrg class_vtab_field_get (tree decl, int fieldno)
359 1.1 mrg {
360 1.1 mrg tree vptr;
361 1.1 mrg vptr = gfc_class_vptr_get (decl);
362 1.1 mrg return vptr_field_get (vptr, fieldno);
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg
366 1.1 mrg /* Define a macro for creating the class_vtab_* and vptr_* accessors in
367 1.1 mrg unison. */
368 1.1 mrg #define VTAB_GET_FIELD_GEN(name, field) tree \
369 1.1 mrg gfc_class_vtab_## name ##_get (tree cl) \
370 1.1 mrg { \
371 1.1 mrg return class_vtab_field_get (cl, field); \
372 1.1 mrg } \
373 1.1 mrg \
374 1.1 mrg tree \
375 1.1 mrg gfc_vptr_## name ##_get (tree vptr) \
376 1.1 mrg { \
377 1.1 mrg return vptr_field_get (vptr, field); \
378 1.1 mrg }
379 1.1 mrg
380 1.1 mrg VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
381 1.1 mrg VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
382 1.1 mrg VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
383 1.1 mrg VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
384 1.1 mrg VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
385 1.1 mrg VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
386 1.1 mrg #undef VTAB_GET_FIELD_GEN
387 1.1 mrg
388 1.1 mrg /* The size field is returned as an array index type. Therefore treat
389 1.1 mrg it and only it specially. */
390 1.1 mrg
391 1.1 mrg tree
392 1.1 mrg gfc_class_vtab_size_get (tree cl)
393 1.1 mrg {
394 1.1 mrg tree size;
395 1.1 mrg size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
396 1.1 mrg /* Always return size as an array index type. */
397 1.1 mrg size = fold_convert (gfc_array_index_type, size);
398 1.1 mrg gcc_assert (size);
399 1.1 mrg return size;
400 1.1 mrg }
401 1.1 mrg
402 1.1 mrg tree
403 1.1 mrg gfc_vptr_size_get (tree vptr)
404 1.1 mrg {
405 1.1 mrg tree size;
406 1.1 mrg size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
407 1.1 mrg /* Always return size as an array index type. */
408 1.1 mrg size = fold_convert (gfc_array_index_type, size);
409 1.1 mrg gcc_assert (size);
410 1.1 mrg return size;
411 1.1 mrg }
412 1.1 mrg
413 1.1 mrg
414 1.1 mrg #undef CLASS_DATA_FIELD
415 1.1 mrg #undef CLASS_VPTR_FIELD
416 1.1 mrg #undef CLASS_LEN_FIELD
417 1.1 mrg #undef VTABLE_HASH_FIELD
418 1.1 mrg #undef VTABLE_SIZE_FIELD
419 1.1 mrg #undef VTABLE_EXTENDS_FIELD
420 1.1 mrg #undef VTABLE_DEF_INIT_FIELD
421 1.1 mrg #undef VTABLE_COPY_FIELD
422 1.1 mrg #undef VTABLE_FINAL_FIELD
423 1.1 mrg
424 1.1 mrg
425 1.1 mrg /* IF ts is null (default), search for the last _class ref in the chain
426 1.1 mrg of references of the expression and cut the chain there. Although
427 1.1 mrg this routine is similiar to class.cc:gfc_add_component_ref (), there
428 1.1 mrg is a significant difference: gfc_add_component_ref () concentrates
429 1.1 mrg on an array ref that is the last ref in the chain and is oblivious
430 1.1 mrg to the kind of refs following.
431 1.1 mrg ELSE IF ts is non-null the cut is at the class entity or component
432 1.1 mrg that is followed by an array reference, which is not an element.
433 1.1 mrg These calls come from trans-array.cc:build_class_array_ref, which
434 1.1 mrg handles scalarized class array references.*/
435 1.1 mrg
436 1.1 mrg gfc_expr *
437 1.1 mrg gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
438 1.1 mrg gfc_typespec **ts)
439 1.1 mrg {
440 1.1 mrg gfc_expr *base_expr;
441 1.1 mrg gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
442 1.1 mrg
443 1.1 mrg /* Find the last class reference. */
444 1.1 mrg class_ref = NULL;
445 1.1 mrg array_ref = NULL;
446 1.1 mrg
447 1.1 mrg if (ts)
448 1.1 mrg {
449 1.1 mrg if (e->symtree
450 1.1 mrg && e->symtree->n.sym->ts.type == BT_CLASS)
451 1.1 mrg *ts = &e->symtree->n.sym->ts;
452 1.1 mrg else
453 1.1 mrg *ts = NULL;
454 1.1 mrg }
455 1.1 mrg
456 1.1 mrg for (ref = e->ref; ref; ref = ref->next)
457 1.1 mrg {
458 1.1 mrg if (ts)
459 1.1 mrg {
460 1.1 mrg if (ref->type == REF_COMPONENT
461 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS
462 1.1 mrg && ref->next && ref->next->type == REF_COMPONENT
463 1.1 mrg && !strcmp (ref->next->u.c.component->name, "_data")
464 1.1 mrg && ref->next->next
465 1.1 mrg && ref->next->next->type == REF_ARRAY
466 1.1 mrg && ref->next->next->u.ar.type != AR_ELEMENT)
467 1.1 mrg {
468 1.1 mrg *ts = &ref->u.c.component->ts;
469 1.1 mrg class_ref = ref;
470 1.1 mrg break;
471 1.1 mrg }
472 1.1 mrg
473 1.1 mrg if (ref->next == NULL)
474 1.1 mrg break;
475 1.1 mrg }
476 1.1 mrg else
477 1.1 mrg {
478 1.1 mrg if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
479 1.1 mrg array_ref = ref;
480 1.1 mrg
481 1.1 mrg if (ref->type == REF_COMPONENT
482 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS)
483 1.1 mrg {
484 1.1 mrg /* Component to the right of a part reference with nonzero
485 1.1 mrg rank must not have the ALLOCATABLE attribute. If attempts
486 1.1 mrg are made to reference such a component reference, an error
487 1.1 mrg results followed by an ICE. */
488 1.1 mrg if (array_ref
489 1.1 mrg && CLASS_DATA (ref->u.c.component)->attr.allocatable)
490 1.1 mrg return NULL;
491 1.1 mrg class_ref = ref;
492 1.1 mrg }
493 1.1 mrg }
494 1.1 mrg }
495 1.1 mrg
496 1.1 mrg if (ts && *ts == NULL)
497 1.1 mrg return NULL;
498 1.1 mrg
499 1.1 mrg /* Remove and store all subsequent references after the
500 1.1 mrg CLASS reference. */
501 1.1 mrg if (class_ref)
502 1.1 mrg {
503 1.1 mrg tail = class_ref->next;
504 1.1 mrg class_ref->next = NULL;
505 1.1 mrg }
506 1.1 mrg else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
507 1.1 mrg {
508 1.1 mrg tail = e->ref;
509 1.1 mrg e->ref = NULL;
510 1.1 mrg }
511 1.1 mrg
512 1.1 mrg if (is_mold)
513 1.1 mrg base_expr = gfc_expr_to_initialize (e);
514 1.1 mrg else
515 1.1 mrg base_expr = gfc_copy_expr (e);
516 1.1 mrg
517 1.1 mrg /* Restore the original tail expression. */
518 1.1 mrg if (class_ref)
519 1.1 mrg {
520 1.1 mrg gfc_free_ref_list (class_ref->next);
521 1.1 mrg class_ref->next = tail;
522 1.1 mrg }
523 1.1 mrg else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
524 1.1 mrg {
525 1.1 mrg gfc_free_ref_list (e->ref);
526 1.1 mrg e->ref = tail;
527 1.1 mrg }
528 1.1 mrg return base_expr;
529 1.1 mrg }
530 1.1 mrg
531 1.1 mrg
532 1.1 mrg /* Reset the vptr to the declared type, e.g. after deallocation. */
533 1.1 mrg
534 1.1 mrg void
535 1.1 mrg gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
536 1.1 mrg {
537 1.1 mrg gfc_symbol *vtab;
538 1.1 mrg tree vptr;
539 1.1 mrg tree vtable;
540 1.1 mrg gfc_se se;
541 1.1 mrg
542 1.1 mrg /* Evaluate the expression and obtain the vptr from it. */
543 1.1 mrg gfc_init_se (&se, NULL);
544 1.1 mrg if (e->rank)
545 1.1 mrg gfc_conv_expr_descriptor (&se, e);
546 1.1 mrg else
547 1.1 mrg gfc_conv_expr (&se, e);
548 1.1 mrg gfc_add_block_to_block (block, &se.pre);
549 1.1 mrg vptr = gfc_get_vptr_from_expr (se.expr);
550 1.1 mrg
551 1.1 mrg /* If a vptr is not found, we can do nothing more. */
552 1.1 mrg if (vptr == NULL_TREE)
553 1.1 mrg return;
554 1.1 mrg
555 1.1 mrg if (UNLIMITED_POLY (e))
556 1.1 mrg gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
557 1.1 mrg else
558 1.1 mrg {
559 1.1 mrg /* Return the vptr to the address of the declared type. */
560 1.1 mrg vtab = gfc_find_derived_vtab (e->ts.u.derived);
561 1.1 mrg vtable = vtab->backend_decl;
562 1.1 mrg if (vtable == NULL_TREE)
563 1.1 mrg vtable = gfc_get_symbol_decl (vtab);
564 1.1 mrg vtable = gfc_build_addr_expr (NULL, vtable);
565 1.1 mrg vtable = fold_convert (TREE_TYPE (vptr), vtable);
566 1.1 mrg gfc_add_modify (block, vptr, vtable);
567 1.1 mrg }
568 1.1 mrg }
569 1.1 mrg
570 1.1 mrg
571 1.1 mrg /* Reset the len for unlimited polymorphic objects. */
572 1.1 mrg
573 1.1 mrg void
574 1.1 mrg gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
575 1.1 mrg {
576 1.1 mrg gfc_expr *e;
577 1.1 mrg gfc_se se_len;
578 1.1 mrg e = gfc_find_and_cut_at_last_class_ref (expr);
579 1.1 mrg if (e == NULL)
580 1.1 mrg return;
581 1.1 mrg gfc_add_len_component (e);
582 1.1 mrg gfc_init_se (&se_len, NULL);
583 1.1 mrg gfc_conv_expr (&se_len, e);
584 1.1 mrg gfc_add_modify (block, se_len.expr,
585 1.1 mrg fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
586 1.1 mrg gfc_free_expr (e);
587 1.1 mrg }
588 1.1 mrg
589 1.1 mrg
590 1.1 mrg /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
591 1.1 mrg reference is found. Note that it is up to the caller to avoid using this
592 1.1 mrg for expressions other than variables. */
593 1.1 mrg
594 1.1 mrg tree
595 1.1 mrg gfc_get_class_from_gfc_expr (gfc_expr *e)
596 1.1 mrg {
597 1.1 mrg gfc_expr *class_expr;
598 1.1 mrg gfc_se cse;
599 1.1 mrg class_expr = gfc_find_and_cut_at_last_class_ref (e);
600 1.1 mrg if (class_expr == NULL)
601 1.1 mrg return NULL_TREE;
602 1.1 mrg gfc_init_se (&cse, NULL);
603 1.1 mrg gfc_conv_expr (&cse, class_expr);
604 1.1 mrg gfc_free_expr (class_expr);
605 1.1 mrg return cse.expr;
606 1.1 mrg }
607 1.1 mrg
608 1.1 mrg
609 1.1 mrg /* Obtain the last class reference in an expression.
610 1.1 mrg Return NULL_TREE if no class reference is found. */
611 1.1 mrg
612 1.1 mrg tree
613 1.1 mrg gfc_get_class_from_expr (tree expr)
614 1.1 mrg {
615 1.1 mrg tree tmp;
616 1.1 mrg tree type;
617 1.1 mrg
618 1.1 mrg for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
619 1.1 mrg {
620 1.1 mrg if (CONSTANT_CLASS_P (tmp))
621 1.1 mrg return NULL_TREE;
622 1.1 mrg
623 1.1 mrg type = TREE_TYPE (tmp);
624 1.1 mrg while (type)
625 1.1 mrg {
626 1.1 mrg if (GFC_CLASS_TYPE_P (type))
627 1.1 mrg return tmp;
628 1.1 mrg if (type != TYPE_CANONICAL (type))
629 1.1 mrg type = TYPE_CANONICAL (type);
630 1.1 mrg else
631 1.1 mrg type = NULL_TREE;
632 1.1 mrg }
633 1.1 mrg if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
634 1.1 mrg break;
635 1.1 mrg }
636 1.1 mrg
637 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (tmp)))
638 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
639 1.1 mrg
640 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
641 1.1 mrg return tmp;
642 1.1 mrg
643 1.1 mrg return NULL_TREE;
644 1.1 mrg }
645 1.1 mrg
646 1.1 mrg
647 1.1 mrg /* Obtain the vptr of the last class reference in an expression.
648 1.1 mrg Return NULL_TREE if no class reference is found. */
649 1.1 mrg
650 1.1 mrg tree
651 1.1 mrg gfc_get_vptr_from_expr (tree expr)
652 1.1 mrg {
653 1.1 mrg tree tmp;
654 1.1 mrg
655 1.1 mrg tmp = gfc_get_class_from_expr (expr);
656 1.1 mrg
657 1.1 mrg if (tmp != NULL_TREE)
658 1.1 mrg return gfc_class_vptr_get (tmp);
659 1.1 mrg
660 1.1 mrg return NULL_TREE;
661 1.1 mrg }
662 1.1 mrg
663 1.1 mrg
664 1.1 mrg static void
665 1.1 mrg class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
666 1.1 mrg bool lhs_type)
667 1.1 mrg {
668 1.1 mrg tree tmp, tmp2, type;
669 1.1 mrg
670 1.1 mrg gfc_conv_descriptor_data_set (block, lhs_desc,
671 1.1 mrg gfc_conv_descriptor_data_get (rhs_desc));
672 1.1 mrg gfc_conv_descriptor_offset_set (block, lhs_desc,
673 1.1 mrg gfc_conv_descriptor_offset_get (rhs_desc));
674 1.1 mrg
675 1.1 mrg gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
676 1.1 mrg gfc_conv_descriptor_dtype (rhs_desc));
677 1.1 mrg
678 1.1 mrg /* Assign the dimension as range-ref. */
679 1.1 mrg tmp = gfc_get_descriptor_dimension (lhs_desc);
680 1.1 mrg tmp2 = gfc_get_descriptor_dimension (rhs_desc);
681 1.1 mrg
682 1.1 mrg type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
683 1.1 mrg tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
684 1.1 mrg gfc_index_zero_node, NULL_TREE, NULL_TREE);
685 1.1 mrg tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
686 1.1 mrg gfc_index_zero_node, NULL_TREE, NULL_TREE);
687 1.1 mrg gfc_add_modify (block, tmp, tmp2);
688 1.1 mrg }
689 1.1 mrg
690 1.1 mrg
691 1.1 mrg /* Takes a derived type expression and returns the address of a temporary
692 1.1 mrg class object of the 'declared' type. If vptr is not NULL, this is
693 1.1 mrg used for the temporary class object.
694 1.1 mrg optional_alloc_ptr is false when the dummy is neither allocatable
695 1.1 mrg nor a pointer; that's only relevant for the optional handling.
696 1.1 mrg The optional argument 'derived_array' is used to preserve the parmse
697 1.1 mrg expression for deallocation of allocatable components. Assumed rank
698 1.1 mrg formal arguments made this necessary. */
699 1.1 mrg void
700 1.1 mrg gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
701 1.1 mrg gfc_typespec class_ts, tree vptr, bool optional,
702 1.1 mrg bool optional_alloc_ptr,
703 1.1 mrg tree *derived_array)
704 1.1 mrg {
705 1.1 mrg gfc_symbol *vtab;
706 1.1 mrg tree cond_optional = NULL_TREE;
707 1.1 mrg gfc_ss *ss;
708 1.1 mrg tree ctree;
709 1.1 mrg tree var;
710 1.1 mrg tree tmp;
711 1.1 mrg int dim;
712 1.1 mrg
713 1.1 mrg /* The derived type needs to be converted to a temporary
714 1.1 mrg CLASS object. */
715 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts);
716 1.1 mrg var = gfc_create_var (tmp, "class");
717 1.1 mrg
718 1.1 mrg /* Set the vptr. */
719 1.1 mrg ctree = gfc_class_vptr_get (var);
720 1.1 mrg
721 1.1 mrg if (vptr != NULL_TREE)
722 1.1 mrg {
723 1.1 mrg /* Use the dynamic vptr. */
724 1.1 mrg tmp = vptr;
725 1.1 mrg }
726 1.1 mrg else
727 1.1 mrg {
728 1.1 mrg /* In this case the vtab corresponds to the derived type and the
729 1.1 mrg vptr must point to it. */
730 1.1 mrg vtab = gfc_find_derived_vtab (e->ts.u.derived);
731 1.1 mrg gcc_assert (vtab);
732 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
733 1.1 mrg }
734 1.1 mrg gfc_add_modify (&parmse->pre, ctree,
735 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp));
736 1.1 mrg
737 1.1 mrg /* Now set the data field. */
738 1.1 mrg ctree = gfc_class_data_get (var);
739 1.1 mrg
740 1.1 mrg if (optional)
741 1.1 mrg cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
742 1.1 mrg
743 1.1 mrg if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
744 1.1 mrg {
745 1.1 mrg /* If there is a ready made pointer to a derived type, use it
746 1.1 mrg rather than evaluating the expression again. */
747 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
748 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
749 1.1 mrg }
750 1.1 mrg else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
751 1.1 mrg {
752 1.1 mrg /* For an array reference in an elemental procedure call we need
753 1.1 mrg to retain the ss to provide the scalarized array reference. */
754 1.1 mrg gfc_conv_expr_reference (parmse, e);
755 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
756 1.1 mrg if (optional)
757 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
758 1.1 mrg cond_optional, tmp,
759 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node));
760 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
761 1.1 mrg }
762 1.1 mrg else
763 1.1 mrg {
764 1.1 mrg ss = gfc_walk_expr (e);
765 1.1 mrg if (ss == gfc_ss_terminator)
766 1.1 mrg {
767 1.1 mrg parmse->ss = NULL;
768 1.1 mrg gfc_conv_expr_reference (parmse, e);
769 1.1 mrg
770 1.1 mrg /* Scalar to an assumed-rank array. */
771 1.1 mrg if (class_ts.u.derived->components->as)
772 1.1 mrg {
773 1.1 mrg tree type;
774 1.1 mrg type = get_scalar_to_descriptor_type (parmse->expr,
775 1.1 mrg gfc_expr_attr (e));
776 1.1 mrg gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
777 1.1 mrg gfc_get_dtype (type));
778 1.1 mrg if (optional)
779 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR,
780 1.1 mrg TREE_TYPE (parmse->expr),
781 1.1 mrg cond_optional, parmse->expr,
782 1.1 mrg fold_convert (TREE_TYPE (parmse->expr),
783 1.1 mrg null_pointer_node));
784 1.1 mrg gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
785 1.1 mrg }
786 1.1 mrg else
787 1.1 mrg {
788 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
789 1.1 mrg if (optional)
790 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
791 1.1 mrg cond_optional, tmp,
792 1.1 mrg fold_convert (TREE_TYPE (tmp),
793 1.1 mrg null_pointer_node));
794 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
795 1.1 mrg }
796 1.1 mrg }
797 1.1 mrg else
798 1.1 mrg {
799 1.1 mrg stmtblock_t block;
800 1.1 mrg gfc_init_block (&block);
801 1.1 mrg gfc_ref *ref;
802 1.1 mrg
803 1.1 mrg parmse->ss = ss;
804 1.1 mrg parmse->use_offset = 1;
805 1.1 mrg gfc_conv_expr_descriptor (parmse, e);
806 1.1 mrg
807 1.1 mrg /* Detect any array references with vector subscripts. */
808 1.1 mrg for (ref = e->ref; ref; ref = ref->next)
809 1.1 mrg if (ref->type == REF_ARRAY
810 1.1 mrg && ref->u.ar.type != AR_ELEMENT
811 1.1 mrg && ref->u.ar.type != AR_FULL)
812 1.1 mrg {
813 1.1 mrg for (dim = 0; dim < ref->u.ar.dimen; dim++)
814 1.1 mrg if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
815 1.1 mrg break;
816 1.1 mrg if (dim < ref->u.ar.dimen)
817 1.1 mrg break;
818 1.1 mrg }
819 1.1 mrg
820 1.1 mrg /* Array references with vector subscripts and non-variable expressions
821 1.1 mrg need be converted to a one-based descriptor. */
822 1.1 mrg if (ref || e->expr_type != EXPR_VARIABLE)
823 1.1 mrg {
824 1.1 mrg for (dim = 0; dim < e->rank; ++dim)
825 1.1 mrg gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
826 1.1 mrg gfc_index_one_node);
827 1.1 mrg }
828 1.1 mrg
829 1.1 mrg if (e->rank != class_ts.u.derived->components->as->rank)
830 1.1 mrg {
831 1.1 mrg gcc_assert (class_ts.u.derived->components->as->type
832 1.1 mrg == AS_ASSUMED_RANK);
833 1.1 mrg if (derived_array
834 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
835 1.1 mrg {
836 1.1 mrg *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
837 1.1 mrg "array");
838 1.1 mrg gfc_add_modify (&block, *derived_array , parmse->expr);
839 1.1 mrg }
840 1.1 mrg class_array_data_assign (&block, ctree, parmse->expr, false);
841 1.1 mrg }
842 1.1 mrg else
843 1.1 mrg {
844 1.1 mrg if (gfc_expr_attr (e).codimension)
845 1.1 mrg parmse->expr = fold_build1_loc (input_location,
846 1.1 mrg VIEW_CONVERT_EXPR,
847 1.1 mrg TREE_TYPE (ctree),
848 1.1 mrg parmse->expr);
849 1.1 mrg gfc_add_modify (&block, ctree, parmse->expr);
850 1.1 mrg }
851 1.1 mrg
852 1.1 mrg if (optional)
853 1.1 mrg {
854 1.1 mrg tmp = gfc_finish_block (&block);
855 1.1 mrg
856 1.1 mrg gfc_init_block (&block);
857 1.1 mrg gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
858 1.1 mrg if (derived_array && *derived_array != NULL_TREE)
859 1.1 mrg gfc_conv_descriptor_data_set (&block, *derived_array,
860 1.1 mrg null_pointer_node);
861 1.1 mrg
862 1.1 mrg tmp = build3_v (COND_EXPR, cond_optional, tmp,
863 1.1 mrg gfc_finish_block (&block));
864 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp);
865 1.1 mrg }
866 1.1 mrg else
867 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block);
868 1.1 mrg }
869 1.1 mrg }
870 1.1 mrg
871 1.1 mrg if (class_ts.u.derived->components->ts.type == BT_DERIVED
872 1.1 mrg && class_ts.u.derived->components->ts.u.derived
873 1.1 mrg ->attr.unlimited_polymorphic)
874 1.1 mrg {
875 1.1 mrg /* Take care about initializing the _len component correctly. */
876 1.1 mrg ctree = gfc_class_len_get (var);
877 1.1 mrg if (UNLIMITED_POLY (e))
878 1.1 mrg {
879 1.1 mrg gfc_expr *len;
880 1.1 mrg gfc_se se;
881 1.1 mrg
882 1.1 mrg len = gfc_find_and_cut_at_last_class_ref (e);
883 1.1 mrg gfc_add_len_component (len);
884 1.1 mrg gfc_init_se (&se, NULL);
885 1.1 mrg gfc_conv_expr (&se, len);
886 1.1 mrg if (optional)
887 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
888 1.1 mrg cond_optional, se.expr,
889 1.1 mrg fold_convert (TREE_TYPE (se.expr),
890 1.1 mrg integer_zero_node));
891 1.1 mrg else
892 1.1 mrg tmp = se.expr;
893 1.1 mrg gfc_free_expr (len);
894 1.1 mrg }
895 1.1 mrg else
896 1.1 mrg tmp = integer_zero_node;
897 1.1 mrg gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
898 1.1 mrg tmp));
899 1.1 mrg }
900 1.1 mrg /* Pass the address of the class object. */
901 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
902 1.1 mrg
903 1.1 mrg if (optional && optional_alloc_ptr)
904 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR,
905 1.1 mrg TREE_TYPE (parmse->expr),
906 1.1 mrg cond_optional, parmse->expr,
907 1.1 mrg fold_convert (TREE_TYPE (parmse->expr),
908 1.1 mrg null_pointer_node));
909 1.1 mrg }
910 1.1 mrg
911 1.1 mrg
912 1.1 mrg /* Create a new class container, which is required as scalar coarrays
913 1.1 mrg have an array descriptor while normal scalars haven't. Optionally,
914 1.1 mrg NULL pointer checks are added if the argument is OPTIONAL. */
915 1.1 mrg
916 1.1 mrg static void
917 1.1 mrg class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
918 1.1 mrg gfc_typespec class_ts, bool optional)
919 1.1 mrg {
920 1.1 mrg tree var, ctree, tmp;
921 1.1 mrg stmtblock_t block;
922 1.1 mrg gfc_ref *ref;
923 1.1 mrg gfc_ref *class_ref;
924 1.1 mrg
925 1.1 mrg gfc_init_block (&block);
926 1.1 mrg
927 1.1 mrg class_ref = NULL;
928 1.1 mrg for (ref = e->ref; ref; ref = ref->next)
929 1.1 mrg {
930 1.1 mrg if (ref->type == REF_COMPONENT
931 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS)
932 1.1 mrg class_ref = ref;
933 1.1 mrg }
934 1.1 mrg
935 1.1 mrg if (class_ref == NULL
936 1.1 mrg && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
937 1.1 mrg tmp = e->symtree->n.sym->backend_decl;
938 1.1 mrg else
939 1.1 mrg {
940 1.1 mrg /* Remove everything after the last class reference, convert the
941 1.1 mrg expression and then recover its tailend once more. */
942 1.1 mrg gfc_se tmpse;
943 1.1 mrg ref = class_ref->next;
944 1.1 mrg class_ref->next = NULL;
945 1.1 mrg gfc_init_se (&tmpse, NULL);
946 1.1 mrg gfc_conv_expr (&tmpse, e);
947 1.1 mrg class_ref->next = ref;
948 1.1 mrg tmp = tmpse.expr;
949 1.1 mrg }
950 1.1 mrg
951 1.1 mrg var = gfc_typenode_for_spec (&class_ts);
952 1.1 mrg var = gfc_create_var (var, "class");
953 1.1 mrg
954 1.1 mrg ctree = gfc_class_vptr_get (var);
955 1.1 mrg gfc_add_modify (&block, ctree,
956 1.1 mrg fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
957 1.1 mrg
958 1.1 mrg ctree = gfc_class_data_get (var);
959 1.1 mrg tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
960 1.1 mrg gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
961 1.1 mrg
962 1.1 mrg /* Pass the address of the class object. */
963 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
964 1.1 mrg
965 1.1 mrg if (optional)
966 1.1 mrg {
967 1.1 mrg tree cond = gfc_conv_expr_present (e->symtree->n.sym);
968 1.1 mrg tree tmp2;
969 1.1 mrg
970 1.1 mrg tmp = gfc_finish_block (&block);
971 1.1 mrg
972 1.1 mrg gfc_init_block (&block);
973 1.1 mrg tmp2 = gfc_class_data_get (var);
974 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
975 1.1 mrg null_pointer_node));
976 1.1 mrg tmp2 = gfc_finish_block (&block);
977 1.1 mrg
978 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, void_type_node,
979 1.1 mrg cond, tmp, tmp2);
980 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp);
981 1.1 mrg }
982 1.1 mrg else
983 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block);
984 1.1 mrg }
985 1.1 mrg
986 1.1 mrg
987 1.1 mrg /* Takes an intrinsic type expression and returns the address of a temporary
988 1.1 mrg class object of the 'declared' type. */
989 1.1 mrg void
990 1.1 mrg gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
991 1.1 mrg gfc_typespec class_ts)
992 1.1 mrg {
993 1.1 mrg gfc_symbol *vtab;
994 1.1 mrg gfc_ss *ss;
995 1.1 mrg tree ctree;
996 1.1 mrg tree var;
997 1.1 mrg tree tmp;
998 1.1 mrg int dim;
999 1.1 mrg
1000 1.1 mrg /* The intrinsic type needs to be converted to a temporary
1001 1.1 mrg CLASS object. */
1002 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts);
1003 1.1 mrg var = gfc_create_var (tmp, "class");
1004 1.1 mrg
1005 1.1 mrg /* Set the vptr. */
1006 1.1 mrg ctree = gfc_class_vptr_get (var);
1007 1.1 mrg
1008 1.1 mrg vtab = gfc_find_vtab (&e->ts);
1009 1.1 mrg gcc_assert (vtab);
1010 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
1011 1.1 mrg gfc_add_modify (&parmse->pre, ctree,
1012 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp));
1013 1.1 mrg
1014 1.1 mrg /* Now set the data field. */
1015 1.1 mrg ctree = gfc_class_data_get (var);
1016 1.1 mrg if (parmse->ss && parmse->ss->info->useflags)
1017 1.1 mrg {
1018 1.1 mrg /* For an array reference in an elemental procedure call we need
1019 1.1 mrg to retain the ss to provide the scalarized array reference. */
1020 1.1 mrg gfc_conv_expr_reference (parmse, e);
1021 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1022 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
1023 1.1 mrg }
1024 1.1 mrg else
1025 1.1 mrg {
1026 1.1 mrg ss = gfc_walk_expr (e);
1027 1.1 mrg if (ss == gfc_ss_terminator)
1028 1.1 mrg {
1029 1.1 mrg parmse->ss = NULL;
1030 1.1 mrg gfc_conv_expr_reference (parmse, e);
1031 1.1 mrg if (class_ts.u.derived->components->as
1032 1.1 mrg && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
1033 1.1 mrg {
1034 1.1 mrg tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
1035 1.1 mrg gfc_expr_attr (e));
1036 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1037 1.1 mrg TREE_TYPE (ctree), tmp);
1038 1.1 mrg }
1039 1.1 mrg else
1040 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1041 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
1042 1.1 mrg }
1043 1.1 mrg else
1044 1.1 mrg {
1045 1.1 mrg parmse->ss = ss;
1046 1.1 mrg parmse->use_offset = 1;
1047 1.1 mrg gfc_conv_expr_descriptor (parmse, e);
1048 1.1 mrg
1049 1.1 mrg /* Array references with vector subscripts and non-variable expressions
1050 1.1 mrg need be converted to a one-based descriptor. */
1051 1.1 mrg if (e->expr_type != EXPR_VARIABLE)
1052 1.1 mrg {
1053 1.1 mrg for (dim = 0; dim < e->rank; ++dim)
1054 1.1 mrg gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
1055 1.1 mrg dim, gfc_index_one_node);
1056 1.1 mrg }
1057 1.1 mrg
1058 1.1 mrg if (class_ts.u.derived->components->as->rank != e->rank)
1059 1.1 mrg {
1060 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1061 1.1 mrg TREE_TYPE (ctree), parmse->expr);
1062 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp);
1063 1.1 mrg }
1064 1.1 mrg else
1065 1.1 mrg gfc_add_modify (&parmse->pre, ctree, parmse->expr);
1066 1.1 mrg }
1067 1.1 mrg }
1068 1.1 mrg
1069 1.1 mrg gcc_assert (class_ts.type == BT_CLASS);
1070 1.1 mrg if (class_ts.u.derived->components->ts.type == BT_DERIVED
1071 1.1 mrg && class_ts.u.derived->components->ts.u.derived
1072 1.1 mrg ->attr.unlimited_polymorphic)
1073 1.1 mrg {
1074 1.1 mrg ctree = gfc_class_len_get (var);
1075 1.1 mrg /* When the actual arg is a char array, then set the _len component of the
1076 1.1 mrg unlimited polymorphic entity to the length of the string. */
1077 1.1 mrg if (e->ts.type == BT_CHARACTER)
1078 1.1 mrg {
1079 1.1 mrg /* Start with parmse->string_length because this seems to be set to a
1080 1.1 mrg correct value more often. */
1081 1.1 mrg if (parmse->string_length)
1082 1.1 mrg tmp = parmse->string_length;
1083 1.1 mrg /* When the string_length is not yet set, then try the backend_decl of
1084 1.1 mrg the cl. */
1085 1.1 mrg else if (e->ts.u.cl->backend_decl)
1086 1.1 mrg tmp = e->ts.u.cl->backend_decl;
1087 1.1 mrg /* If both of the above approaches fail, then try to generate an
1088 1.1 mrg expression from the input, which is only feasible currently, when the
1089 1.1 mrg expression can be evaluated to a constant one. */
1090 1.1 mrg else
1091 1.1 mrg {
1092 1.1 mrg /* Try to simplify the expression. */
1093 1.1 mrg gfc_simplify_expr (e, 0);
1094 1.1 mrg if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
1095 1.1 mrg {
1096 1.1 mrg /* Amazingly all data is present to compute the length of a
1097 1.1 mrg constant string, but the expression is not yet there. */
1098 1.1 mrg e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
1099 1.1 mrg gfc_charlen_int_kind,
1100 1.1 mrg &e->where);
1101 1.1 mrg mpz_set_ui (e->ts.u.cl->length->value.integer,
1102 1.1 mrg e->value.character.length);
1103 1.1 mrg gfc_conv_const_charlen (e->ts.u.cl);
1104 1.1 mrg e->ts.u.cl->resolved = 1;
1105 1.1 mrg tmp = e->ts.u.cl->backend_decl;
1106 1.1 mrg }
1107 1.1 mrg else
1108 1.1 mrg {
1109 1.1 mrg gfc_error ("Cannot compute the length of the char array "
1110 1.1 mrg "at %L.", &e->where);
1111 1.1 mrg }
1112 1.1 mrg }
1113 1.1 mrg }
1114 1.1 mrg else
1115 1.1 mrg tmp = integer_zero_node;
1116 1.1 mrg
1117 1.1 mrg gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
1118 1.1 mrg }
1119 1.1 mrg else if (class_ts.type == BT_CLASS
1120 1.1 mrg && class_ts.u.derived->components
1121 1.1 mrg && class_ts.u.derived->components->ts.u
1122 1.1 mrg .derived->attr.unlimited_polymorphic)
1123 1.1 mrg {
1124 1.1 mrg ctree = gfc_class_len_get (var);
1125 1.1 mrg gfc_add_modify (&parmse->pre, ctree,
1126 1.1 mrg fold_convert (TREE_TYPE (ctree),
1127 1.1 mrg integer_zero_node));
1128 1.1 mrg }
1129 1.1 mrg /* Pass the address of the class object. */
1130 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1131 1.1 mrg }
1132 1.1 mrg
1133 1.1 mrg
1134 1.1 mrg /* Takes a scalarized class array expression and returns the
1135 1.1 mrg address of a temporary scalar class object of the 'declared'
1136 1.1 mrg type.
1137 1.1 mrg OOP-TODO: This could be improved by adding code that branched on
1138 1.1 mrg the dynamic type being the same as the declared type. In this case
1139 1.1 mrg the original class expression can be passed directly.
1140 1.1 mrg optional_alloc_ptr is false when the dummy is neither allocatable
1141 1.1 mrg nor a pointer; that's relevant for the optional handling.
1142 1.1 mrg Set copyback to true if class container's _data and _vtab pointers
1143 1.1 mrg might get modified. */
1144 1.1 mrg
1145 1.1 mrg void
1146 1.1 mrg gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
1147 1.1 mrg bool elemental, bool copyback, bool optional,
1148 1.1 mrg bool optional_alloc_ptr)
1149 1.1 mrg {
1150 1.1 mrg tree ctree;
1151 1.1 mrg tree var;
1152 1.1 mrg tree tmp;
1153 1.1 mrg tree vptr;
1154 1.1 mrg tree cond = NULL_TREE;
1155 1.1 mrg tree slen = NULL_TREE;
1156 1.1 mrg gfc_ref *ref;
1157 1.1 mrg gfc_ref *class_ref;
1158 1.1 mrg stmtblock_t block;
1159 1.1 mrg bool full_array = false;
1160 1.1 mrg
1161 1.1 mrg gfc_init_block (&block);
1162 1.1 mrg
1163 1.1 mrg class_ref = NULL;
1164 1.1 mrg for (ref = e->ref; ref; ref = ref->next)
1165 1.1 mrg {
1166 1.1 mrg if (ref->type == REF_COMPONENT
1167 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS)
1168 1.1 mrg class_ref = ref;
1169 1.1 mrg
1170 1.1 mrg if (ref->next == NULL)
1171 1.1 mrg break;
1172 1.1 mrg }
1173 1.1 mrg
1174 1.1 mrg if ((ref == NULL || class_ref == ref)
1175 1.1 mrg && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
1176 1.1 mrg && (!class_ts.u.derived->components->as
1177 1.1 mrg || class_ts.u.derived->components->as->rank != -1))
1178 1.1 mrg return;
1179 1.1 mrg
1180 1.1 mrg /* Test for FULL_ARRAY. */
1181 1.1 mrg if (e->rank == 0
1182 1.1 mrg && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension)
1183 1.1 mrg || (class_ts.u.derived->components->as
1184 1.1 mrg && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)))
1185 1.1 mrg full_array = true;
1186 1.1 mrg else
1187 1.1 mrg gfc_is_class_array_ref (e, &full_array);
1188 1.1 mrg
1189 1.1 mrg /* The derived type needs to be converted to a temporary
1190 1.1 mrg CLASS object. */
1191 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts);
1192 1.1 mrg var = gfc_create_var (tmp, "class");
1193 1.1 mrg
1194 1.1 mrg /* Set the data. */
1195 1.1 mrg ctree = gfc_class_data_get (var);
1196 1.1 mrg if (class_ts.u.derived->components->as
1197 1.1 mrg && e->rank != class_ts.u.derived->components->as->rank)
1198 1.1 mrg {
1199 1.1 mrg if (e->rank == 0)
1200 1.1 mrg {
1201 1.1 mrg tree type = get_scalar_to_descriptor_type (parmse->expr,
1202 1.1 mrg gfc_expr_attr (e));
1203 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1204 1.1 mrg gfc_get_dtype (type));
1205 1.1 mrg
1206 1.1 mrg tmp = gfc_class_data_get (parmse->expr);
1207 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1208 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1209 1.1 mrg
1210 1.1 mrg gfc_conv_descriptor_data_set (&block, ctree, tmp);
1211 1.1 mrg }
1212 1.1 mrg else
1213 1.1 mrg class_array_data_assign (&block, ctree, parmse->expr, false);
1214 1.1 mrg }
1215 1.1 mrg else
1216 1.1 mrg {
1217 1.1 mrg if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1218 1.1 mrg parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1219 1.1 mrg TREE_TYPE (ctree), parmse->expr);
1220 1.1 mrg gfc_add_modify (&block, ctree, parmse->expr);
1221 1.1 mrg }
1222 1.1 mrg
1223 1.1 mrg /* Return the data component, except in the case of scalarized array
1224 1.1 mrg references, where nullification of the cannot occur and so there
1225 1.1 mrg is no need. */
1226 1.1 mrg if (!elemental && full_array && copyback)
1227 1.1 mrg {
1228 1.1 mrg if (class_ts.u.derived->components->as
1229 1.1 mrg && e->rank != class_ts.u.derived->components->as->rank)
1230 1.1 mrg {
1231 1.1 mrg if (e->rank == 0)
1232 1.1 mrg {
1233 1.1 mrg tmp = gfc_class_data_get (parmse->expr);
1234 1.1 mrg gfc_add_modify (&parmse->post, tmp,
1235 1.1 mrg fold_convert (TREE_TYPE (tmp),
1236 1.1 mrg gfc_conv_descriptor_data_get (ctree)));
1237 1.1 mrg }
1238 1.1 mrg else
1239 1.1 mrg class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1240 1.1 mrg }
1241 1.1 mrg else
1242 1.1 mrg gfc_add_modify (&parmse->post, parmse->expr, ctree);
1243 1.1 mrg }
1244 1.1 mrg
1245 1.1 mrg /* Set the vptr. */
1246 1.1 mrg ctree = gfc_class_vptr_get (var);
1247 1.1 mrg
1248 1.1 mrg /* The vptr is the second field of the actual argument.
1249 1.1 mrg First we have to find the corresponding class reference. */
1250 1.1 mrg
1251 1.1 mrg tmp = NULL_TREE;
1252 1.1 mrg if (gfc_is_class_array_function (e)
1253 1.1 mrg && parmse->class_vptr != NULL_TREE)
1254 1.1 mrg tmp = parmse->class_vptr;
1255 1.1 mrg else if (class_ref == NULL
1256 1.1 mrg && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1257 1.1 mrg {
1258 1.1 mrg tmp = e->symtree->n.sym->backend_decl;
1259 1.1 mrg
1260 1.1 mrg if (TREE_CODE (tmp) == FUNCTION_DECL)
1261 1.1 mrg tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1262 1.1 mrg
1263 1.1 mrg if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1264 1.1 mrg tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1265 1.1 mrg
1266 1.1 mrg slen = build_zero_cst (size_type_node);
1267 1.1 mrg }
1268 1.1 mrg else
1269 1.1 mrg {
1270 1.1 mrg /* Remove everything after the last class reference, convert the
1271 1.1 mrg expression and then recover its tailend once more. */
1272 1.1 mrg gfc_se tmpse;
1273 1.1 mrg ref = class_ref->next;
1274 1.1 mrg class_ref->next = NULL;
1275 1.1 mrg gfc_init_se (&tmpse, NULL);
1276 1.1 mrg gfc_conv_expr (&tmpse, e);
1277 1.1 mrg class_ref->next = ref;
1278 1.1 mrg tmp = tmpse.expr;
1279 1.1 mrg slen = tmpse.string_length;
1280 1.1 mrg }
1281 1.1 mrg
1282 1.1 mrg gcc_assert (tmp != NULL_TREE);
1283 1.1 mrg
1284 1.1 mrg /* Dereference if needs be. */
1285 1.1 mrg if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1286 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
1287 1.1 mrg
1288 1.1 mrg if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1289 1.1 mrg vptr = gfc_class_vptr_get (tmp);
1290 1.1 mrg else
1291 1.1 mrg vptr = tmp;
1292 1.1 mrg
1293 1.1 mrg gfc_add_modify (&block, ctree,
1294 1.1 mrg fold_convert (TREE_TYPE (ctree), vptr));
1295 1.1 mrg
1296 1.1 mrg /* Return the vptr component, except in the case of scalarized array
1297 1.1 mrg references, where the dynamic type cannot change. */
1298 1.1 mrg if (!elemental && full_array && copyback)
1299 1.1 mrg gfc_add_modify (&parmse->post, vptr,
1300 1.1 mrg fold_convert (TREE_TYPE (vptr), ctree));
1301 1.1 mrg
1302 1.1 mrg /* For unlimited polymorphic objects also set the _len component. */
1303 1.1 mrg if (class_ts.type == BT_CLASS
1304 1.1 mrg && class_ts.u.derived->components
1305 1.1 mrg && class_ts.u.derived->components->ts.u
1306 1.1 mrg .derived->attr.unlimited_polymorphic)
1307 1.1 mrg {
1308 1.1 mrg ctree = gfc_class_len_get (var);
1309 1.1 mrg if (UNLIMITED_POLY (e))
1310 1.1 mrg tmp = gfc_class_len_get (tmp);
1311 1.1 mrg else if (e->ts.type == BT_CHARACTER)
1312 1.1 mrg {
1313 1.1 mrg gcc_assert (slen != NULL_TREE);
1314 1.1 mrg tmp = slen;
1315 1.1 mrg }
1316 1.1 mrg else
1317 1.1 mrg tmp = build_zero_cst (size_type_node);
1318 1.1 mrg gfc_add_modify (&parmse->pre, ctree,
1319 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp));
1320 1.1 mrg
1321 1.1 mrg /* Return the len component, except in the case of scalarized array
1322 1.1 mrg references, where the dynamic type cannot change. */
1323 1.1 mrg if (!elemental && full_array && copyback
1324 1.1 mrg && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1325 1.1 mrg gfc_add_modify (&parmse->post, tmp,
1326 1.1 mrg fold_convert (TREE_TYPE (tmp), ctree));
1327 1.1 mrg }
1328 1.1 mrg
1329 1.1 mrg if (optional)
1330 1.1 mrg {
1331 1.1 mrg tree tmp2;
1332 1.1 mrg
1333 1.1 mrg cond = gfc_conv_expr_present (e->symtree->n.sym);
1334 1.1 mrg /* parmse->pre may contain some preparatory instructions for the
1335 1.1 mrg temporary array descriptor. Those may only be executed when the
1336 1.1 mrg optional argument is set, therefore add parmse->pre's instructions
1337 1.1 mrg to block, which is later guarded by an if (optional_arg_given). */
1338 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block);
1339 1.1 mrg block.head = parmse->pre.head;
1340 1.1 mrg parmse->pre.head = NULL_TREE;
1341 1.1 mrg tmp = gfc_finish_block (&block);
1342 1.1 mrg
1343 1.1 mrg if (optional_alloc_ptr)
1344 1.1 mrg tmp2 = build_empty_stmt (input_location);
1345 1.1 mrg else
1346 1.1 mrg {
1347 1.1 mrg gfc_init_block (&block);
1348 1.1 mrg
1349 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1350 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1351 1.1 mrg null_pointer_node));
1352 1.1 mrg tmp2 = gfc_finish_block (&block);
1353 1.1 mrg }
1354 1.1 mrg
1355 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1356 1.1 mrg cond, tmp, tmp2);
1357 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp);
1358 1.1 mrg }
1359 1.1 mrg else
1360 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block);
1361 1.1 mrg
1362 1.1 mrg /* Pass the address of the class object. */
1363 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1364 1.1 mrg
1365 1.1 mrg if (optional && optional_alloc_ptr)
1366 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR,
1367 1.1 mrg TREE_TYPE (parmse->expr),
1368 1.1 mrg cond, parmse->expr,
1369 1.1 mrg fold_convert (TREE_TYPE (parmse->expr),
1370 1.1 mrg null_pointer_node));
1371 1.1 mrg }
1372 1.1 mrg
1373 1.1 mrg
1374 1.1 mrg /* Given a class array declaration and an index, returns the address
1375 1.1 mrg of the referenced element. */
1376 1.1 mrg
1377 1.1 mrg static tree
1378 1.1 mrg gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1379 1.1 mrg bool unlimited)
1380 1.1 mrg {
1381 1.1 mrg tree data, size, tmp, ctmp, offset, ptr;
1382 1.1 mrg
1383 1.1 mrg data = data_comp != NULL_TREE ? data_comp :
1384 1.1 mrg gfc_class_data_get (class_decl);
1385 1.1 mrg size = gfc_class_vtab_size_get (class_decl);
1386 1.1 mrg
1387 1.1 mrg if (unlimited)
1388 1.1 mrg {
1389 1.1 mrg tmp = fold_convert (gfc_array_index_type,
1390 1.1 mrg gfc_class_len_get (class_decl));
1391 1.1 mrg ctmp = fold_build2_loc (input_location, MULT_EXPR,
1392 1.1 mrg gfc_array_index_type, size, tmp);
1393 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR,
1394 1.1 mrg logical_type_node, tmp,
1395 1.1 mrg build_zero_cst (TREE_TYPE (tmp)));
1396 1.1 mrg size = fold_build3_loc (input_location, COND_EXPR,
1397 1.1 mrg gfc_array_index_type, tmp, ctmp, size);
1398 1.1 mrg }
1399 1.1 mrg
1400 1.1 mrg offset = fold_build2_loc (input_location, MULT_EXPR,
1401 1.1 mrg gfc_array_index_type,
1402 1.1 mrg index, size);
1403 1.1 mrg
1404 1.1 mrg data = gfc_conv_descriptor_data_get (data);
1405 1.1 mrg ptr = fold_convert (pvoid_type_node, data);
1406 1.1 mrg ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1407 1.1 mrg return fold_convert (TREE_TYPE (data), ptr);
1408 1.1 mrg }
1409 1.1 mrg
1410 1.1 mrg
1411 1.1 mrg /* Copies one class expression to another, assuming that if either
1412 1.1 mrg 'to' or 'from' are arrays they are packed. Should 'from' be
1413 1.1 mrg NULL_TREE, the initialization expression for 'to' is used, assuming
1414 1.1 mrg that the _vptr is set. */
1415 1.1 mrg
1416 1.1 mrg tree
1417 1.1 mrg gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1418 1.1 mrg {
1419 1.1 mrg tree fcn;
1420 1.1 mrg tree fcn_type;
1421 1.1 mrg tree from_data;
1422 1.1 mrg tree from_len;
1423 1.1 mrg tree to_data;
1424 1.1 mrg tree to_len;
1425 1.1 mrg tree to_ref;
1426 1.1 mrg tree from_ref;
1427 1.1 mrg vec<tree, va_gc> *args;
1428 1.1 mrg tree tmp;
1429 1.1 mrg tree stdcopy;
1430 1.1 mrg tree extcopy;
1431 1.1 mrg tree index;
1432 1.1 mrg bool is_from_desc = false, is_to_class = false;
1433 1.1 mrg
1434 1.1 mrg args = NULL;
1435 1.1 mrg /* To prevent warnings on uninitialized variables. */
1436 1.1 mrg from_len = to_len = NULL_TREE;
1437 1.1 mrg
1438 1.1 mrg if (from != NULL_TREE)
1439 1.1 mrg fcn = gfc_class_vtab_copy_get (from);
1440 1.1 mrg else
1441 1.1 mrg fcn = gfc_class_vtab_copy_get (to);
1442 1.1 mrg
1443 1.1 mrg fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1444 1.1 mrg
1445 1.1 mrg if (from != NULL_TREE)
1446 1.1 mrg {
1447 1.1 mrg is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1448 1.1 mrg if (is_from_desc)
1449 1.1 mrg {
1450 1.1 mrg from_data = from;
1451 1.1 mrg from = GFC_DECL_SAVED_DESCRIPTOR (from);
1452 1.1 mrg }
1453 1.1 mrg else
1454 1.1 mrg {
1455 1.1 mrg /* Check that from is a class. When the class is part of a coarray,
1456 1.1 mrg then from is a common pointer and is to be used as is. */
1457 1.1 mrg tmp = POINTER_TYPE_P (TREE_TYPE (from))
1458 1.1 mrg ? build_fold_indirect_ref (from) : from;
1459 1.1 mrg from_data =
1460 1.1 mrg (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1461 1.1 mrg || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1462 1.1 mrg ? gfc_class_data_get (from) : from;
1463 1.1 mrg is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1464 1.1 mrg }
1465 1.1 mrg }
1466 1.1 mrg else
1467 1.1 mrg from_data = gfc_class_vtab_def_init_get (to);
1468 1.1 mrg
1469 1.1 mrg if (unlimited)
1470 1.1 mrg {
1471 1.1 mrg if (from != NULL_TREE && unlimited)
1472 1.1 mrg from_len = gfc_class_len_or_zero_get (from);
1473 1.1 mrg else
1474 1.1 mrg from_len = build_zero_cst (size_type_node);
1475 1.1 mrg }
1476 1.1 mrg
1477 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1478 1.1 mrg {
1479 1.1 mrg is_to_class = true;
1480 1.1 mrg to_data = gfc_class_data_get (to);
1481 1.1 mrg if (unlimited)
1482 1.1 mrg to_len = gfc_class_len_get (to);
1483 1.1 mrg }
1484 1.1 mrg else
1485 1.1 mrg /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1486 1.1 mrg to_data = to;
1487 1.1 mrg
1488 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1489 1.1 mrg {
1490 1.1 mrg stmtblock_t loopbody;
1491 1.1 mrg stmtblock_t body;
1492 1.1 mrg stmtblock_t ifbody;
1493 1.1 mrg gfc_loopinfo loop;
1494 1.1 mrg tree orig_nelems = nelems; /* Needed for bounds check. */
1495 1.1 mrg
1496 1.1 mrg gfc_init_block (&body);
1497 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
1498 1.1 mrg gfc_array_index_type, nelems,
1499 1.1 mrg gfc_index_one_node);
1500 1.1 mrg nelems = gfc_evaluate_now (tmp, &body);
1501 1.1 mrg index = gfc_create_var (gfc_array_index_type, "S");
1502 1.1 mrg
1503 1.1 mrg if (is_from_desc)
1504 1.1 mrg {
1505 1.1 mrg from_ref = gfc_get_class_array_ref (index, from, from_data,
1506 1.1 mrg unlimited);
1507 1.1 mrg vec_safe_push (args, from_ref);
1508 1.1 mrg }
1509 1.1 mrg else
1510 1.1 mrg vec_safe_push (args, from_data);
1511 1.1 mrg
1512 1.1 mrg if (is_to_class)
1513 1.1 mrg to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1514 1.1 mrg else
1515 1.1 mrg {
1516 1.1 mrg tmp = gfc_conv_array_data (to);
1517 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
1518 1.1 mrg to_ref = gfc_build_addr_expr (NULL_TREE,
1519 1.1 mrg gfc_build_array_ref (tmp, index, to));
1520 1.1 mrg }
1521 1.1 mrg vec_safe_push (args, to_ref);
1522 1.1 mrg
1523 1.1 mrg /* Add bounds check. */
1524 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1525 1.1 mrg {
1526 1.1 mrg char *msg;
1527 1.1 mrg const char *name = "<<unknown>>";
1528 1.1 mrg tree from_len;
1529 1.1 mrg
1530 1.1 mrg if (DECL_P (to))
1531 1.1 mrg name = (const char *)(DECL_NAME (to)->identifier.id.str);
1532 1.1 mrg
1533 1.1 mrg from_len = gfc_conv_descriptor_size (from_data, 1);
1534 1.1 mrg from_len = fold_convert (TREE_TYPE (orig_nelems), from_len);
1535 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
1536 1.1 mrg logical_type_node, from_len, orig_nelems);
1537 1.1 mrg msg = xasprintf ("Array bound mismatch for dimension %d "
1538 1.1 mrg "of array '%s' (%%ld/%%ld)",
1539 1.1 mrg 1, name);
1540 1.1 mrg
1541 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &body,
1542 1.1 mrg &gfc_current_locus, msg,
1543 1.1 mrg fold_convert (long_integer_type_node, orig_nelems),
1544 1.1 mrg fold_convert (long_integer_type_node, from_len));
1545 1.1 mrg
1546 1.1 mrg free (msg);
1547 1.1 mrg }
1548 1.1 mrg
1549 1.1 mrg tmp = build_call_vec (fcn_type, fcn, args);
1550 1.1 mrg
1551 1.1 mrg /* Build the body of the loop. */
1552 1.1 mrg gfc_init_block (&loopbody);
1553 1.1 mrg gfc_add_expr_to_block (&loopbody, tmp);
1554 1.1 mrg
1555 1.1 mrg /* Build the loop and return. */
1556 1.1 mrg gfc_init_loopinfo (&loop);
1557 1.1 mrg loop.dimen = 1;
1558 1.1 mrg loop.from[0] = gfc_index_zero_node;
1559 1.1 mrg loop.loopvar[0] = index;
1560 1.1 mrg loop.to[0] = nelems;
1561 1.1 mrg gfc_trans_scalarizing_loops (&loop, &loopbody);
1562 1.1 mrg gfc_init_block (&ifbody);
1563 1.1 mrg gfc_add_block_to_block (&ifbody, &loop.pre);
1564 1.1 mrg stdcopy = gfc_finish_block (&ifbody);
1565 1.1 mrg /* In initialization mode from_len is a constant zero. */
1566 1.1 mrg if (unlimited && !integer_zerop (from_len))
1567 1.1 mrg {
1568 1.1 mrg vec_safe_push (args, from_len);
1569 1.1 mrg vec_safe_push (args, to_len);
1570 1.1 mrg tmp = build_call_vec (fcn_type, fcn, args);
1571 1.1 mrg /* Build the body of the loop. */
1572 1.1 mrg gfc_init_block (&loopbody);
1573 1.1 mrg gfc_add_expr_to_block (&loopbody, tmp);
1574 1.1 mrg
1575 1.1 mrg /* Build the loop and return. */
1576 1.1 mrg gfc_init_loopinfo (&loop);
1577 1.1 mrg loop.dimen = 1;
1578 1.1 mrg loop.from[0] = gfc_index_zero_node;
1579 1.1 mrg loop.loopvar[0] = index;
1580 1.1 mrg loop.to[0] = nelems;
1581 1.1 mrg gfc_trans_scalarizing_loops (&loop, &loopbody);
1582 1.1 mrg gfc_init_block (&ifbody);
1583 1.1 mrg gfc_add_block_to_block (&ifbody, &loop.pre);
1584 1.1 mrg extcopy = gfc_finish_block (&ifbody);
1585 1.1 mrg
1586 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR,
1587 1.1 mrg logical_type_node, from_len,
1588 1.1 mrg build_zero_cst (TREE_TYPE (from_len)));
1589 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
1590 1.1 mrg void_type_node, tmp, extcopy, stdcopy);
1591 1.1 mrg gfc_add_expr_to_block (&body, tmp);
1592 1.1 mrg tmp = gfc_finish_block (&body);
1593 1.1 mrg }
1594 1.1 mrg else
1595 1.1 mrg {
1596 1.1 mrg gfc_add_expr_to_block (&body, stdcopy);
1597 1.1 mrg tmp = gfc_finish_block (&body);
1598 1.1 mrg }
1599 1.1 mrg gfc_cleanup_loop (&loop);
1600 1.1 mrg }
1601 1.1 mrg else
1602 1.1 mrg {
1603 1.1 mrg gcc_assert (!is_from_desc);
1604 1.1 mrg vec_safe_push (args, from_data);
1605 1.1 mrg vec_safe_push (args, to_data);
1606 1.1 mrg stdcopy = build_call_vec (fcn_type, fcn, args);
1607 1.1 mrg
1608 1.1 mrg /* In initialization mode from_len is a constant zero. */
1609 1.1 mrg if (unlimited && !integer_zerop (from_len))
1610 1.1 mrg {
1611 1.1 mrg vec_safe_push (args, from_len);
1612 1.1 mrg vec_safe_push (args, to_len);
1613 1.1 mrg extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
1614 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR,
1615 1.1 mrg logical_type_node, from_len,
1616 1.1 mrg build_zero_cst (TREE_TYPE (from_len)));
1617 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
1618 1.1 mrg void_type_node, tmp, extcopy, stdcopy);
1619 1.1 mrg }
1620 1.1 mrg else
1621 1.1 mrg tmp = stdcopy;
1622 1.1 mrg }
1623 1.1 mrg
1624 1.1 mrg /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1625 1.1 mrg if (from == NULL_TREE)
1626 1.1 mrg {
1627 1.1 mrg tree cond;
1628 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR,
1629 1.1 mrg logical_type_node,
1630 1.1 mrg from_data, null_pointer_node);
1631 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
1632 1.1 mrg void_type_node, cond,
1633 1.1 mrg tmp, build_empty_stmt (input_location));
1634 1.1 mrg }
1635 1.1 mrg
1636 1.1 mrg return tmp;
1637 1.1 mrg }
1638 1.1 mrg
1639 1.1 mrg
1640 1.1 mrg static tree
1641 1.1 mrg gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1642 1.1 mrg {
1643 1.1 mrg gfc_actual_arglist *actual;
1644 1.1 mrg gfc_expr *ppc;
1645 1.1 mrg gfc_code *ppc_code;
1646 1.1 mrg tree res;
1647 1.1 mrg
1648 1.1 mrg actual = gfc_get_actual_arglist ();
1649 1.1 mrg actual->expr = gfc_copy_expr (rhs);
1650 1.1 mrg actual->next = gfc_get_actual_arglist ();
1651 1.1 mrg actual->next->expr = gfc_copy_expr (lhs);
1652 1.1 mrg ppc = gfc_copy_expr (obj);
1653 1.1 mrg gfc_add_vptr_component (ppc);
1654 1.1 mrg gfc_add_component_ref (ppc, "_copy");
1655 1.1 mrg ppc_code = gfc_get_code (EXEC_CALL);
1656 1.1 mrg ppc_code->resolved_sym = ppc->symtree->n.sym;
1657 1.1 mrg /* Although '_copy' is set to be elemental in class.cc, it is
1658 1.1 mrg not staying that way. Find out why, sometime.... */
1659 1.1 mrg ppc_code->resolved_sym->attr.elemental = 1;
1660 1.1 mrg ppc_code->ext.actual = actual;
1661 1.1 mrg ppc_code->expr1 = ppc;
1662 1.1 mrg /* Since '_copy' is elemental, the scalarizer will take care
1663 1.1 mrg of arrays in gfc_trans_call. */
1664 1.1 mrg res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1665 1.1 mrg gfc_free_statements (ppc_code);
1666 1.1 mrg
1667 1.1 mrg if (UNLIMITED_POLY(obj))
1668 1.1 mrg {
1669 1.1 mrg /* Check if rhs is non-NULL. */
1670 1.1 mrg gfc_se src;
1671 1.1 mrg gfc_init_se (&src, NULL);
1672 1.1 mrg gfc_conv_expr (&src, rhs);
1673 1.1 mrg src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1674 1.1 mrg tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1675 1.1 mrg src.expr, fold_convert (TREE_TYPE (src.expr),
1676 1.1 mrg null_pointer_node));
1677 1.1 mrg res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1678 1.1 mrg build_empty_stmt (input_location));
1679 1.1 mrg }
1680 1.1 mrg
1681 1.1 mrg return res;
1682 1.1 mrg }
1683 1.1 mrg
1684 1.1 mrg /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1685 1.1 mrg A MEMCPY is needed to copy the full data from the default initializer
1686 1.1 mrg of the dynamic type. */
1687 1.1 mrg
1688 1.1 mrg tree
1689 1.1 mrg gfc_trans_class_init_assign (gfc_code *code)
1690 1.1 mrg {
1691 1.1 mrg stmtblock_t block;
1692 1.1 mrg tree tmp;
1693 1.1 mrg gfc_se dst,src,memsz;
1694 1.1 mrg gfc_expr *lhs, *rhs, *sz;
1695 1.1 mrg
1696 1.1 mrg gfc_start_block (&block);
1697 1.1 mrg
1698 1.1 mrg lhs = gfc_copy_expr (code->expr1);
1699 1.1 mrg
1700 1.1 mrg rhs = gfc_copy_expr (code->expr1);
1701 1.1 mrg gfc_add_vptr_component (rhs);
1702 1.1 mrg
1703 1.1 mrg /* Make sure that the component backend_decls have been built, which
1704 1.1 mrg will not have happened if the derived types concerned have not
1705 1.1 mrg been referenced. */
1706 1.1 mrg gfc_get_derived_type (rhs->ts.u.derived);
1707 1.1 mrg gfc_add_def_init_component (rhs);
1708 1.1 mrg /* The _def_init is always scalar. */
1709 1.1 mrg rhs->rank = 0;
1710 1.1 mrg
1711 1.1 mrg if (code->expr1->ts.type == BT_CLASS
1712 1.1 mrg && CLASS_DATA (code->expr1)->attr.dimension)
1713 1.1 mrg {
1714 1.1 mrg gfc_array_spec *tmparr = gfc_get_array_spec ();
1715 1.1 mrg *tmparr = *CLASS_DATA (code->expr1)->as;
1716 1.1 mrg /* Adding the array ref to the class expression results in correct
1717 1.1 mrg indexing to the dynamic type. */
1718 1.1 mrg gfc_add_full_array_ref (lhs, tmparr);
1719 1.1 mrg tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1720 1.1 mrg }
1721 1.1 mrg else
1722 1.1 mrg {
1723 1.1 mrg /* Scalar initialization needs the _data component. */
1724 1.1 mrg gfc_add_data_component (lhs);
1725 1.1 mrg sz = gfc_copy_expr (code->expr1);
1726 1.1 mrg gfc_add_vptr_component (sz);
1727 1.1 mrg gfc_add_size_component (sz);
1728 1.1 mrg
1729 1.1 mrg gfc_init_se (&dst, NULL);
1730 1.1 mrg gfc_init_se (&src, NULL);
1731 1.1 mrg gfc_init_se (&memsz, NULL);
1732 1.1 mrg gfc_conv_expr (&dst, lhs);
1733 1.1 mrg gfc_conv_expr (&src, rhs);
1734 1.1 mrg gfc_conv_expr (&memsz, sz);
1735 1.1 mrg gfc_add_block_to_block (&block, &src.pre);
1736 1.1 mrg src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1737 1.1 mrg
1738 1.1 mrg tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1739 1.1 mrg
1740 1.1 mrg if (UNLIMITED_POLY(code->expr1))
1741 1.1 mrg {
1742 1.1 mrg /* Check if _def_init is non-NULL. */
1743 1.1 mrg tree cond = fold_build2_loc (input_location, NE_EXPR,
1744 1.1 mrg logical_type_node, src.expr,
1745 1.1 mrg fold_convert (TREE_TYPE (src.expr),
1746 1.1 mrg null_pointer_node));
1747 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1748 1.1 mrg tmp, build_empty_stmt (input_location));
1749 1.1 mrg }
1750 1.1 mrg }
1751 1.1 mrg
1752 1.1 mrg if (code->expr1->symtree->n.sym->attr.dummy
1753 1.1 mrg && (code->expr1->symtree->n.sym->attr.optional
1754 1.1 mrg || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
1755 1.1 mrg {
1756 1.1 mrg tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1757 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1758 1.1 mrg present, tmp,
1759 1.1 mrg build_empty_stmt (input_location));
1760 1.1 mrg }
1761 1.1 mrg
1762 1.1 mrg gfc_add_expr_to_block (&block, tmp);
1763 1.1 mrg
1764 1.1 mrg return gfc_finish_block (&block);
1765 1.1 mrg }
1766 1.1 mrg
1767 1.1 mrg
1768 1.1 mrg /* Class valued elemental function calls or class array elements arriving
1769 1.1 mrg in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1770 1.1 mrg is used to ensure that the rhs dynamic type is assigned to the lhs. */
1771 1.1 mrg
1772 1.1 mrg static bool
1773 1.1 mrg trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
1774 1.1 mrg {
1775 1.1 mrg tree fcn;
1776 1.1 mrg tree rse_expr;
1777 1.1 mrg tree class_data;
1778 1.1 mrg tree tmp;
1779 1.1 mrg tree zero;
1780 1.1 mrg tree cond;
1781 1.1 mrg tree final_cond;
1782 1.1 mrg stmtblock_t inner_block;
1783 1.1 mrg bool is_descriptor;
1784 1.1 mrg bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
1785 1.1 mrg bool not_lhs_array_type;
1786 1.1 mrg
1787 1.1 mrg /* Temporaries arising from dependencies in assignment get cast as a
1788 1.1 mrg character type of the dynamic size of the rhs. Use the vptr copy
1789 1.1 mrg for this case. */
1790 1.1 mrg tmp = TREE_TYPE (lse->expr);
1791 1.1 mrg not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
1792 1.1 mrg && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
1793 1.1 mrg
1794 1.1 mrg /* Use ordinary assignment if the rhs is not a call expression or
1795 1.1 mrg the lhs is not a class entity or an array(ie. character) type. */
1796 1.1 mrg if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
1797 1.1 mrg && not_lhs_array_type)
1798 1.1 mrg return false;
1799 1.1 mrg
1800 1.1 mrg /* Ordinary assignment can be used if both sides are class expressions
1801 1.1 mrg since the dynamic type is preserved by copying the vptr. This
1802 1.1 mrg should only occur, where temporaries are involved. */
1803 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
1804 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
1805 1.1 mrg return false;
1806 1.1 mrg
1807 1.1 mrg /* Fix the class expression and the class data of the rhs. */
1808 1.1 mrg if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
1809 1.1 mrg || not_call_expr)
1810 1.1 mrg {
1811 1.1 mrg tmp = gfc_get_class_from_expr (rse->expr);
1812 1.1 mrg if (tmp == NULL_TREE)
1813 1.1 mrg return false;
1814 1.1 mrg rse_expr = gfc_evaluate_now (tmp, block);
1815 1.1 mrg }
1816 1.1 mrg else
1817 1.1 mrg rse_expr = gfc_evaluate_now (rse->expr, block);
1818 1.1 mrg
1819 1.1 mrg class_data = gfc_class_data_get (rse_expr);
1820 1.1 mrg
1821 1.1 mrg /* Check that the rhs data is not null. */
1822 1.1 mrg is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
1823 1.1 mrg if (is_descriptor)
1824 1.1 mrg class_data = gfc_conv_descriptor_data_get (class_data);
1825 1.1 mrg class_data = gfc_evaluate_now (class_data, block);
1826 1.1 mrg
1827 1.1 mrg zero = build_int_cst (TREE_TYPE (class_data), 0);
1828 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR,
1829 1.1 mrg logical_type_node,
1830 1.1 mrg class_data, zero);
1831 1.1 mrg
1832 1.1 mrg /* Copy the rhs to the lhs. */
1833 1.1 mrg fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
1834 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn);
1835 1.1 mrg tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
1836 1.1 mrg tmp = is_descriptor ? tmp : class_data;
1837 1.1 mrg tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
1838 1.1 mrg gfc_build_addr_expr (NULL, lse->expr));
1839 1.1 mrg gfc_add_expr_to_block (block, tmp);
1840 1.1 mrg
1841 1.1 mrg /* Only elemental function results need to be finalised and freed. */
1842 1.1 mrg if (not_call_expr)
1843 1.1 mrg return true;
1844 1.1 mrg
1845 1.1 mrg /* Finalize the class data if needed. */
1846 1.1 mrg gfc_init_block (&inner_block);
1847 1.1 mrg fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
1848 1.1 mrg zero = build_int_cst (TREE_TYPE (fcn), 0);
1849 1.1 mrg final_cond = fold_build2_loc (input_location, NE_EXPR,
1850 1.1 mrg logical_type_node, fcn, zero);
1851 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn);
1852 1.1 mrg tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
1853 1.1 mrg tmp = build3_v (COND_EXPR, final_cond,
1854 1.1 mrg tmp, build_empty_stmt (input_location));
1855 1.1 mrg gfc_add_expr_to_block (&inner_block, tmp);
1856 1.1 mrg
1857 1.1 mrg /* Free the class data. */
1858 1.1 mrg tmp = gfc_call_free (class_data);
1859 1.1 mrg tmp = build3_v (COND_EXPR, cond, tmp,
1860 1.1 mrg build_empty_stmt (input_location));
1861 1.1 mrg gfc_add_expr_to_block (&inner_block, tmp);
1862 1.1 mrg
1863 1.1 mrg /* Finish the inner block and subject it to the condition on the
1864 1.1 mrg class data being non-zero. */
1865 1.1 mrg tmp = gfc_finish_block (&inner_block);
1866 1.1 mrg tmp = build3_v (COND_EXPR, cond, tmp,
1867 1.1 mrg build_empty_stmt (input_location));
1868 1.1 mrg gfc_add_expr_to_block (block, tmp);
1869 1.1 mrg
1870 1.1 mrg return true;
1871 1.1 mrg }
1872 1.1 mrg
1873 1.1 mrg /* End of prototype trans-class.c */
1874 1.1 mrg
1875 1.1 mrg
1876 1.1 mrg static void
1877 1.1 mrg realloc_lhs_warning (bt type, bool array, locus *where)
1878 1.1 mrg {
1879 1.1 mrg if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1880 1.1 mrg gfc_warning (OPT_Wrealloc_lhs,
1881 1.1 mrg "Code for reallocating the allocatable array at %L will "
1882 1.1 mrg "be added", where);
1883 1.1 mrg else if (warn_realloc_lhs_all)
1884 1.1 mrg gfc_warning (OPT_Wrealloc_lhs_all,
1885 1.1 mrg "Code for reallocating the allocatable variable at %L "
1886 1.1 mrg "will be added", where);
1887 1.1 mrg }
1888 1.1 mrg
1889 1.1 mrg
1890 1.1 mrg static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1891 1.1 mrg gfc_expr *);
1892 1.1 mrg
1893 1.1 mrg /* Copy the scalarization loop variables. */
1894 1.1 mrg
1895 1.1 mrg static void
1896 1.1 mrg gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1897 1.1 mrg {
1898 1.1 mrg dest->ss = src->ss;
1899 1.1 mrg dest->loop = src->loop;
1900 1.1 mrg }
1901 1.1 mrg
1902 1.1 mrg
1903 1.1 mrg /* Initialize a simple expression holder.
1904 1.1 mrg
1905 1.1 mrg Care must be taken when multiple se are created with the same parent.
1906 1.1 mrg The child se must be kept in sync. The easiest way is to delay creation
1907 1.1 mrg of a child se until after the previous se has been translated. */
1908 1.1 mrg
1909 1.1 mrg void
1910 1.1 mrg gfc_init_se (gfc_se * se, gfc_se * parent)
1911 1.1 mrg {
1912 1.1 mrg memset (se, 0, sizeof (gfc_se));
1913 1.1 mrg gfc_init_block (&se->pre);
1914 1.1 mrg gfc_init_block (&se->post);
1915 1.1 mrg
1916 1.1 mrg se->parent = parent;
1917 1.1 mrg
1918 1.1 mrg if (parent)
1919 1.1 mrg gfc_copy_se_loopvars (se, parent);
1920 1.1 mrg }
1921 1.1 mrg
1922 1.1 mrg
1923 1.1 mrg /* Advances to the next SS in the chain. Use this rather than setting
1924 1.1 mrg se->ss = se->ss->next because all the parents needs to be kept in sync.
1925 1.1 mrg See gfc_init_se. */
1926 1.1 mrg
1927 1.1 mrg void
1928 1.1 mrg gfc_advance_se_ss_chain (gfc_se * se)
1929 1.1 mrg {
1930 1.1 mrg gfc_se *p;
1931 1.1 mrg gfc_ss *ss;
1932 1.1 mrg
1933 1.1 mrg gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1934 1.1 mrg
1935 1.1 mrg p = se;
1936 1.1 mrg /* Walk down the parent chain. */
1937 1.1 mrg while (p != NULL)
1938 1.1 mrg {
1939 1.1 mrg /* Simple consistency check. */
1940 1.1 mrg gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1941 1.1 mrg || p->parent->ss->nested_ss == p->ss);
1942 1.1 mrg
1943 1.1 mrg /* If we were in a nested loop, the next scalarized expression can be
1944 1.1 mrg on the parent ss' next pointer. Thus we should not take the next
1945 1.1 mrg pointer blindly, but rather go up one nest level as long as next
1946 1.1 mrg is the end of chain. */
1947 1.1 mrg ss = p->ss;
1948 1.1 mrg while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1949 1.1 mrg ss = ss->parent;
1950 1.1 mrg
1951 1.1 mrg p->ss = ss->next;
1952 1.1 mrg
1953 1.1 mrg p = p->parent;
1954 1.1 mrg }
1955 1.1 mrg }
1956 1.1 mrg
1957 1.1 mrg
1958 1.1 mrg /* Ensures the result of the expression as either a temporary variable
1959 1.1 mrg or a constant so that it can be used repeatedly. */
1960 1.1 mrg
1961 1.1 mrg void
1962 1.1 mrg gfc_make_safe_expr (gfc_se * se)
1963 1.1 mrg {
1964 1.1 mrg tree var;
1965 1.1 mrg
1966 1.1 mrg if (CONSTANT_CLASS_P (se->expr))
1967 1.1 mrg return;
1968 1.1 mrg
1969 1.1 mrg /* We need a temporary for this result. */
1970 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1971 1.1 mrg gfc_add_modify (&se->pre, var, se->expr);
1972 1.1 mrg se->expr = var;
1973 1.1 mrg }
1974 1.1 mrg
1975 1.1 mrg
1976 1.1 mrg /* Return an expression which determines if a dummy parameter is present.
1977 1.1 mrg Also used for arguments to procedures with multiple entry points. */
1978 1.1 mrg
1979 1.1 mrg tree
1980 1.1 mrg gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
1981 1.1 mrg {
1982 1.1 mrg tree decl, orig_decl, cond;
1983 1.1 mrg
1984 1.1 mrg gcc_assert (sym->attr.dummy);
1985 1.1 mrg orig_decl = decl = gfc_get_symbol_decl (sym);
1986 1.1 mrg
1987 1.1 mrg /* Intrinsic scalars with VALUE attribute which are passed by value
1988 1.1 mrg use a hidden argument to denote the present status. */
1989 1.1 mrg if (sym->attr.value && sym->ts.type != BT_CHARACTER
1990 1.1 mrg && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1991 1.1 mrg && !sym->attr.dimension)
1992 1.1 mrg {
1993 1.1 mrg char name[GFC_MAX_SYMBOL_LEN + 2];
1994 1.1 mrg tree tree_name;
1995 1.1 mrg
1996 1.1 mrg gcc_assert (TREE_CODE (decl) == PARM_DECL);
1997 1.1 mrg name[0] = '_';
1998 1.1 mrg strcpy (&name[1], sym->name);
1999 1.1 mrg tree_name = get_identifier (name);
2000 1.1 mrg
2001 1.1 mrg /* Walk function argument list to find hidden arg. */
2002 1.1 mrg cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
2003 1.1 mrg for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
2004 1.1 mrg if (DECL_NAME (cond) == tree_name
2005 1.1 mrg && DECL_ARTIFICIAL (cond))
2006 1.1 mrg break;
2007 1.1 mrg
2008 1.1 mrg gcc_assert (cond);
2009 1.1 mrg return cond;
2010 1.1 mrg }
2011 1.1 mrg
2012 1.1 mrg /* Assumed-shape arrays use a local variable for the array data;
2013 1.1 mrg the actual PARAM_DECL is in a saved decl. As the local variable
2014 1.1 mrg is NULL, it can be checked instead, unless use_saved_desc is
2015 1.1 mrg requested. */
2016 1.1 mrg
2017 1.1 mrg if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
2018 1.1 mrg {
2019 1.1 mrg gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
2020 1.1 mrg || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
2021 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
2022 1.1 mrg }
2023 1.1 mrg
2024 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
2025 1.1 mrg fold_convert (TREE_TYPE (decl), null_pointer_node));
2026 1.1 mrg
2027 1.1 mrg /* Fortran 2008 allows to pass null pointers and non-associated pointers
2028 1.1 mrg as actual argument to denote absent dummies. For array descriptors,
2029 1.1 mrg we thus also need to check the array descriptor. For BT_CLASS, it
2030 1.1 mrg can also occur for scalars and F2003 due to type->class wrapping and
2031 1.1 mrg class->class wrapping. Note further that BT_CLASS always uses an
2032 1.1 mrg array descriptor for arrays, also for explicit-shape/assumed-size.
2033 1.1 mrg For assumed-rank arrays, no local variable is generated, hence,
2034 1.1 mrg the following also applies with !use_saved_desc. */
2035 1.1 mrg
2036 1.1 mrg if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
2037 1.1 mrg && !sym->attr.allocatable
2038 1.1 mrg && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
2039 1.1 mrg || (sym->ts.type == BT_CLASS
2040 1.1 mrg && !CLASS_DATA (sym)->attr.allocatable
2041 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer))
2042 1.1 mrg && ((gfc_option.allow_std & GFC_STD_F2008) != 0
2043 1.1 mrg || sym->ts.type == BT_CLASS))
2044 1.1 mrg {
2045 1.1 mrg tree tmp;
2046 1.1 mrg
2047 1.1 mrg if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
2048 1.1 mrg || sym->as->type == AS_ASSUMED_RANK
2049 1.1 mrg || sym->attr.codimension))
2050 1.1 mrg || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
2051 1.1 mrg {
2052 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, decl);
2053 1.1 mrg if (sym->ts.type == BT_CLASS)
2054 1.1 mrg tmp = gfc_class_data_get (tmp);
2055 1.1 mrg tmp = gfc_conv_array_data (tmp);
2056 1.1 mrg }
2057 1.1 mrg else if (sym->ts.type == BT_CLASS)
2058 1.1 mrg tmp = gfc_class_data_get (decl);
2059 1.1 mrg else
2060 1.1 mrg tmp = NULL_TREE;
2061 1.1 mrg
2062 1.1 mrg if (tmp != NULL_TREE)
2063 1.1 mrg {
2064 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
2065 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node));
2066 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2067 1.1 mrg logical_type_node, cond, tmp);
2068 1.1 mrg }
2069 1.1 mrg }
2070 1.1 mrg
2071 1.1 mrg return cond;
2072 1.1 mrg }
2073 1.1 mrg
2074 1.1 mrg
2075 1.1 mrg /* Converts a missing, dummy argument into a null or zero. */
2076 1.1 mrg
2077 1.1 mrg void
2078 1.1 mrg gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
2079 1.1 mrg {
2080 1.1 mrg tree present;
2081 1.1 mrg tree tmp;
2082 1.1 mrg
2083 1.1 mrg present = gfc_conv_expr_present (arg->symtree->n.sym);
2084 1.1 mrg
2085 1.1 mrg if (kind > 0)
2086 1.1 mrg {
2087 1.1 mrg /* Create a temporary and convert it to the correct type. */
2088 1.1 mrg tmp = gfc_get_int_type (kind);
2089 1.1 mrg tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
2090 1.1 mrg se->expr));
2091 1.1 mrg
2092 1.1 mrg /* Test for a NULL value. */
2093 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
2094 1.1 mrg tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
2095 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre);
2096 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
2097 1.1 mrg }
2098 1.1 mrg else
2099 1.1 mrg {
2100 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
2101 1.1 mrg present, se->expr,
2102 1.1 mrg build_zero_cst (TREE_TYPE (se->expr)));
2103 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre);
2104 1.1 mrg se->expr = tmp;
2105 1.1 mrg }
2106 1.1 mrg
2107 1.1 mrg if (ts.type == BT_CHARACTER)
2108 1.1 mrg {
2109 1.1 mrg tmp = build_int_cst (gfc_charlen_type_node, 0);
2110 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
2111 1.1 mrg present, se->string_length, tmp);
2112 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre);
2113 1.1 mrg se->string_length = tmp;
2114 1.1 mrg }
2115 1.1 mrg return;
2116 1.1 mrg }
2117 1.1 mrg
2118 1.1 mrg
2119 1.1 mrg /* Get the character length of an expression, looking through gfc_refs
2120 1.1 mrg if necessary. */
2121 1.1 mrg
2122 1.1 mrg tree
2123 1.1 mrg gfc_get_expr_charlen (gfc_expr *e)
2124 1.1 mrg {
2125 1.1 mrg gfc_ref *r;
2126 1.1 mrg tree length;
2127 1.1 mrg gfc_se se;
2128 1.1 mrg
2129 1.1 mrg gcc_assert (e->expr_type == EXPR_VARIABLE
2130 1.1 mrg && e->ts.type == BT_CHARACTER);
2131 1.1 mrg
2132 1.1 mrg length = NULL; /* To silence compiler warning. */
2133 1.1 mrg
2134 1.1 mrg if (is_subref_array (e) && e->ts.u.cl->length)
2135 1.1 mrg {
2136 1.1 mrg gfc_se tmpse;
2137 1.1 mrg gfc_init_se (&tmpse, NULL);
2138 1.1 mrg gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
2139 1.1 mrg e->ts.u.cl->backend_decl = tmpse.expr;
2140 1.1 mrg return tmpse.expr;
2141 1.1 mrg }
2142 1.1 mrg
2143 1.1 mrg /* First candidate: if the variable is of type CHARACTER, the
2144 1.1 mrg expression's length could be the length of the character
2145 1.1 mrg variable. */
2146 1.1 mrg if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2147 1.1 mrg length = e->symtree->n.sym->ts.u.cl->backend_decl;
2148 1.1 mrg
2149 1.1 mrg /* Look through the reference chain for component references. */
2150 1.1 mrg for (r = e->ref; r; r = r->next)
2151 1.1 mrg {
2152 1.1 mrg switch (r->type)
2153 1.1 mrg {
2154 1.1 mrg case REF_COMPONENT:
2155 1.1 mrg if (r->u.c.component->ts.type == BT_CHARACTER)
2156 1.1 mrg length = r->u.c.component->ts.u.cl->backend_decl;
2157 1.1 mrg break;
2158 1.1 mrg
2159 1.1 mrg case REF_ARRAY:
2160 1.1 mrg /* Do nothing. */
2161 1.1 mrg break;
2162 1.1 mrg
2163 1.1 mrg case REF_SUBSTRING:
2164 1.1 mrg gfc_init_se (&se, NULL);
2165 1.1 mrg gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
2166 1.1 mrg length = se.expr;
2167 1.1 mrg gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
2168 1.1 mrg length = fold_build2_loc (input_location, MINUS_EXPR,
2169 1.1 mrg gfc_charlen_type_node,
2170 1.1 mrg se.expr, length);
2171 1.1 mrg length = fold_build2_loc (input_location, PLUS_EXPR,
2172 1.1 mrg gfc_charlen_type_node, length,
2173 1.1 mrg gfc_index_one_node);
2174 1.1 mrg break;
2175 1.1 mrg
2176 1.1 mrg default:
2177 1.1 mrg gcc_unreachable ();
2178 1.1 mrg break;
2179 1.1 mrg }
2180 1.1 mrg }
2181 1.1 mrg
2182 1.1 mrg gcc_assert (length != NULL);
2183 1.1 mrg return length;
2184 1.1 mrg }
2185 1.1 mrg
2186 1.1 mrg
2187 1.1 mrg /* Return for an expression the backend decl of the coarray. */
2188 1.1 mrg
2189 1.1 mrg tree
2190 1.1 mrg gfc_get_tree_for_caf_expr (gfc_expr *expr)
2191 1.1 mrg {
2192 1.1 mrg tree caf_decl;
2193 1.1 mrg bool found = false;
2194 1.1 mrg gfc_ref *ref;
2195 1.1 mrg
2196 1.1 mrg gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
2197 1.1 mrg
2198 1.1 mrg /* Not-implemented diagnostic. */
2199 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_CLASS
2200 1.1 mrg && UNLIMITED_POLY (expr->symtree->n.sym)
2201 1.1 mrg && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2202 1.1 mrg gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2203 1.1 mrg "%L is not supported", &expr->where);
2204 1.1 mrg
2205 1.1 mrg for (ref = expr->ref; ref; ref = ref->next)
2206 1.1 mrg if (ref->type == REF_COMPONENT)
2207 1.1 mrg {
2208 1.1 mrg if (ref->u.c.component->ts.type == BT_CLASS
2209 1.1 mrg && UNLIMITED_POLY (ref->u.c.component)
2210 1.1 mrg && CLASS_DATA (ref->u.c.component)->attr.codimension)
2211 1.1 mrg gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2212 1.1 mrg "component at %L is not supported", &expr->where);
2213 1.1 mrg }
2214 1.1 mrg
2215 1.1 mrg /* Make sure the backend_decl is present before accessing it. */
2216 1.1 mrg caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
2217 1.1 mrg ? gfc_get_symbol_decl (expr->symtree->n.sym)
2218 1.1 mrg : expr->symtree->n.sym->backend_decl;
2219 1.1 mrg
2220 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_CLASS)
2221 1.1 mrg {
2222 1.1 mrg if (expr->ref && expr->ref->type == REF_ARRAY)
2223 1.1 mrg {
2224 1.1 mrg caf_decl = gfc_class_data_get (caf_decl);
2225 1.1 mrg if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2226 1.1 mrg return caf_decl;
2227 1.1 mrg }
2228 1.1 mrg for (ref = expr->ref; ref; ref = ref->next)
2229 1.1 mrg {
2230 1.1 mrg if (ref->type == REF_COMPONENT
2231 1.1 mrg && strcmp (ref->u.c.component->name, "_data") != 0)
2232 1.1 mrg {
2233 1.1 mrg caf_decl = gfc_class_data_get (caf_decl);
2234 1.1 mrg if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2235 1.1 mrg return caf_decl;
2236 1.1 mrg break;
2237 1.1 mrg }
2238 1.1 mrg else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
2239 1.1 mrg break;
2240 1.1 mrg }
2241 1.1 mrg }
2242 1.1 mrg if (expr->symtree->n.sym->attr.codimension)
2243 1.1 mrg return caf_decl;
2244 1.1 mrg
2245 1.1 mrg /* The following code assumes that the coarray is a component reachable via
2246 1.1 mrg only scalar components/variables; the Fortran standard guarantees this. */
2247 1.1 mrg
2248 1.1 mrg for (ref = expr->ref; ref; ref = ref->next)
2249 1.1 mrg if (ref->type == REF_COMPONENT)
2250 1.1 mrg {
2251 1.1 mrg gfc_component *comp = ref->u.c.component;
2252 1.1 mrg
2253 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
2254 1.1 mrg caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
2255 1.1 mrg caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
2256 1.1 mrg TREE_TYPE (comp->backend_decl), caf_decl,
2257 1.1 mrg comp->backend_decl, NULL_TREE);
2258 1.1 mrg if (comp->ts.type == BT_CLASS)
2259 1.1 mrg {
2260 1.1 mrg caf_decl = gfc_class_data_get (caf_decl);
2261 1.1 mrg if (CLASS_DATA (comp)->attr.codimension)
2262 1.1 mrg {
2263 1.1 mrg found = true;
2264 1.1 mrg break;
2265 1.1 mrg }
2266 1.1 mrg }
2267 1.1 mrg if (comp->attr.codimension)
2268 1.1 mrg {
2269 1.1 mrg found = true;
2270 1.1 mrg break;
2271 1.1 mrg }
2272 1.1 mrg }
2273 1.1 mrg gcc_assert (found && caf_decl);
2274 1.1 mrg return caf_decl;
2275 1.1 mrg }
2276 1.1 mrg
2277 1.1 mrg
2278 1.1 mrg /* Obtain the Coarray token - and optionally also the offset. */
2279 1.1 mrg
2280 1.1 mrg void
2281 1.1 mrg gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
2282 1.1 mrg tree se_expr, gfc_expr *expr)
2283 1.1 mrg {
2284 1.1 mrg tree tmp;
2285 1.1 mrg
2286 1.1 mrg /* Coarray token. */
2287 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2288 1.1 mrg {
2289 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
2290 1.1 mrg == GFC_ARRAY_ALLOCATABLE
2291 1.1 mrg || expr->symtree->n.sym->attr.select_type_temporary);
2292 1.1 mrg *token = gfc_conv_descriptor_token (caf_decl);
2293 1.1 mrg }
2294 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl)
2295 1.1 mrg && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
2296 1.1 mrg *token = GFC_DECL_TOKEN (caf_decl);
2297 1.1 mrg else
2298 1.1 mrg {
2299 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2300 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2301 1.1 mrg *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2302 1.1 mrg }
2303 1.1 mrg
2304 1.1 mrg if (offset == NULL)
2305 1.1 mrg return;
2306 1.1 mrg
2307 1.1 mrg /* Offset between the coarray base address and the address wanted. */
2308 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2309 1.1 mrg && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2310 1.1 mrg || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2311 1.1 mrg *offset = build_int_cst (gfc_array_index_type, 0);
2312 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl)
2313 1.1 mrg && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2314 1.1 mrg *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2315 1.1 mrg else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2316 1.1 mrg *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2317 1.1 mrg else
2318 1.1 mrg *offset = build_int_cst (gfc_array_index_type, 0);
2319 1.1 mrg
2320 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2321 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2322 1.1 mrg {
2323 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2324 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp);
2325 1.1 mrg }
2326 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2327 1.1 mrg tmp = gfc_conv_descriptor_data_get (se_expr);
2328 1.1 mrg else
2329 1.1 mrg {
2330 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2331 1.1 mrg tmp = se_expr;
2332 1.1 mrg }
2333 1.1 mrg
2334 1.1 mrg *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2335 1.1 mrg *offset, fold_convert (gfc_array_index_type, tmp));
2336 1.1 mrg
2337 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_DERIVED
2338 1.1 mrg && expr->symtree->n.sym->attr.codimension
2339 1.1 mrg && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2340 1.1 mrg {
2341 1.1 mrg gfc_expr *base_expr = gfc_copy_expr (expr);
2342 1.1 mrg gfc_ref *ref = base_expr->ref;
2343 1.1 mrg gfc_se base_se;
2344 1.1 mrg
2345 1.1 mrg // Iterate through the refs until the last one.
2346 1.1 mrg while (ref->next)
2347 1.1 mrg ref = ref->next;
2348 1.1 mrg
2349 1.1 mrg if (ref->type == REF_ARRAY
2350 1.1 mrg && ref->u.ar.type != AR_FULL)
2351 1.1 mrg {
2352 1.1 mrg const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2353 1.1 mrg int i;
2354 1.1 mrg for (i = 0; i < ranksum; ++i)
2355 1.1 mrg {
2356 1.1 mrg ref->u.ar.start[i] = NULL;
2357 1.1 mrg ref->u.ar.end[i] = NULL;
2358 1.1 mrg }
2359 1.1 mrg ref->u.ar.type = AR_FULL;
2360 1.1 mrg }
2361 1.1 mrg gfc_init_se (&base_se, NULL);
2362 1.1 mrg if (gfc_caf_attr (base_expr).dimension)
2363 1.1 mrg {
2364 1.1 mrg gfc_conv_expr_descriptor (&base_se, base_expr);
2365 1.1 mrg tmp = gfc_conv_descriptor_data_get (base_se.expr);
2366 1.1 mrg }
2367 1.1 mrg else
2368 1.1 mrg {
2369 1.1 mrg gfc_conv_expr (&base_se, base_expr);
2370 1.1 mrg tmp = base_se.expr;
2371 1.1 mrg }
2372 1.1 mrg
2373 1.1 mrg gfc_free_expr (base_expr);
2374 1.1 mrg gfc_add_block_to_block (&se->pre, &base_se.pre);
2375 1.1 mrg gfc_add_block_to_block (&se->post, &base_se.post);
2376 1.1 mrg }
2377 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2378 1.1 mrg tmp = gfc_conv_descriptor_data_get (caf_decl);
2379 1.1 mrg else
2380 1.1 mrg {
2381 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2382 1.1 mrg tmp = caf_decl;
2383 1.1 mrg }
2384 1.1 mrg
2385 1.1 mrg *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2386 1.1 mrg fold_convert (gfc_array_index_type, *offset),
2387 1.1 mrg fold_convert (gfc_array_index_type, tmp));
2388 1.1 mrg }
2389 1.1 mrg
2390 1.1 mrg
2391 1.1 mrg /* Convert the coindex of a coarray into an image index; the result is
2392 1.1 mrg image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2393 1.1 mrg + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2394 1.1 mrg
2395 1.1 mrg tree
2396 1.1 mrg gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2397 1.1 mrg {
2398 1.1 mrg gfc_ref *ref;
2399 1.1 mrg tree lbound, ubound, extent, tmp, img_idx;
2400 1.1 mrg gfc_se se;
2401 1.1 mrg int i;
2402 1.1 mrg
2403 1.1 mrg for (ref = e->ref; ref; ref = ref->next)
2404 1.1 mrg if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2405 1.1 mrg break;
2406 1.1 mrg gcc_assert (ref != NULL);
2407 1.1 mrg
2408 1.1 mrg if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2409 1.1 mrg {
2410 1.1 mrg return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2411 1.1 mrg integer_zero_node);
2412 1.1 mrg }
2413 1.1 mrg
2414 1.1 mrg img_idx = build_zero_cst (gfc_array_index_type);
2415 1.1 mrg extent = build_one_cst (gfc_array_index_type);
2416 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2417 1.1 mrg for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2418 1.1 mrg {
2419 1.1 mrg gfc_init_se (&se, NULL);
2420 1.1 mrg gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2421 1.1 mrg gfc_add_block_to_block (block, &se.pre);
2422 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2423 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
2424 1.1 mrg TREE_TYPE (lbound), se.expr, lbound);
2425 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2426 1.1 mrg extent, tmp);
2427 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2428 1.1 mrg TREE_TYPE (tmp), img_idx, tmp);
2429 1.1 mrg if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2430 1.1 mrg {
2431 1.1 mrg ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2432 1.1 mrg tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2433 1.1 mrg extent = fold_build2_loc (input_location, MULT_EXPR,
2434 1.1 mrg TREE_TYPE (tmp), extent, tmp);
2435 1.1 mrg }
2436 1.1 mrg }
2437 1.1 mrg else
2438 1.1 mrg for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2439 1.1 mrg {
2440 1.1 mrg gfc_init_se (&se, NULL);
2441 1.1 mrg gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2442 1.1 mrg gfc_add_block_to_block (block, &se.pre);
2443 1.1 mrg lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2444 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
2445 1.1 mrg TREE_TYPE (lbound), se.expr, lbound);
2446 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2447 1.1 mrg extent, tmp);
2448 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2449 1.1 mrg img_idx, tmp);
2450 1.1 mrg if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2451 1.1 mrg {
2452 1.1 mrg ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2453 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
2454 1.1 mrg TREE_TYPE (ubound), ubound, lbound);
2455 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2456 1.1 mrg tmp, build_one_cst (TREE_TYPE (tmp)));
2457 1.1 mrg extent = fold_build2_loc (input_location, MULT_EXPR,
2458 1.1 mrg TREE_TYPE (tmp), extent, tmp);
2459 1.1 mrg }
2460 1.1 mrg }
2461 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2462 1.1 mrg img_idx, build_one_cst (TREE_TYPE (img_idx)));
2463 1.1 mrg return fold_convert (integer_type_node, img_idx);
2464 1.1 mrg }
2465 1.1 mrg
2466 1.1 mrg
2467 1.1 mrg /* For each character array constructor subexpression without a ts.u.cl->length,
2468 1.1 mrg replace it by its first element (if there aren't any elements, the length
2469 1.1 mrg should already be set to zero). */
2470 1.1 mrg
2471 1.1 mrg static void
2472 1.1 mrg flatten_array_ctors_without_strlen (gfc_expr* e)
2473 1.1 mrg {
2474 1.1 mrg gfc_actual_arglist* arg;
2475 1.1 mrg gfc_constructor* c;
2476 1.1 mrg
2477 1.1 mrg if (!e)
2478 1.1 mrg return;
2479 1.1 mrg
2480 1.1 mrg switch (e->expr_type)
2481 1.1 mrg {
2482 1.1 mrg
2483 1.1 mrg case EXPR_OP:
2484 1.1 mrg flatten_array_ctors_without_strlen (e->value.op.op1);
2485 1.1 mrg flatten_array_ctors_without_strlen (e->value.op.op2);
2486 1.1 mrg break;
2487 1.1 mrg
2488 1.1 mrg case EXPR_COMPCALL:
2489 1.1 mrg /* TODO: Implement as with EXPR_FUNCTION when needed. */
2490 1.1 mrg gcc_unreachable ();
2491 1.1 mrg
2492 1.1 mrg case EXPR_FUNCTION:
2493 1.1 mrg for (arg = e->value.function.actual; arg; arg = arg->next)
2494 1.1 mrg flatten_array_ctors_without_strlen (arg->expr);
2495 1.1 mrg break;
2496 1.1 mrg
2497 1.1 mrg case EXPR_ARRAY:
2498 1.1 mrg
2499 1.1 mrg /* We've found what we're looking for. */
2500 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2501 1.1 mrg {
2502 1.1 mrg gfc_constructor *c;
2503 1.1 mrg gfc_expr* new_expr;
2504 1.1 mrg
2505 1.1 mrg gcc_assert (e->value.constructor);
2506 1.1 mrg
2507 1.1 mrg c = gfc_constructor_first (e->value.constructor);
2508 1.1 mrg new_expr = c->expr;
2509 1.1 mrg c->expr = NULL;
2510 1.1 mrg
2511 1.1 mrg flatten_array_ctors_without_strlen (new_expr);
2512 1.1 mrg gfc_replace_expr (e, new_expr);
2513 1.1 mrg break;
2514 1.1 mrg }
2515 1.1 mrg
2516 1.1 mrg /* Otherwise, fall through to handle constructor elements. */
2517 1.1 mrg gcc_fallthrough ();
2518 1.1 mrg case EXPR_STRUCTURE:
2519 1.1 mrg for (c = gfc_constructor_first (e->value.constructor);
2520 1.1 mrg c; c = gfc_constructor_next (c))
2521 1.1 mrg flatten_array_ctors_without_strlen (c->expr);
2522 1.1 mrg break;
2523 1.1 mrg
2524 1.1 mrg default:
2525 1.1 mrg break;
2526 1.1 mrg
2527 1.1 mrg }
2528 1.1 mrg }
2529 1.1 mrg
2530 1.1 mrg
2531 1.1 mrg /* Generate code to initialize a string length variable. Returns the
2532 1.1 mrg value. For array constructors, cl->length might be NULL and in this case,
2533 1.1 mrg the first element of the constructor is needed. expr is the original
2534 1.1 mrg expression so we can access it but can be NULL if this is not needed. */
2535 1.1 mrg
2536 1.1 mrg void
2537 1.1 mrg gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2538 1.1 mrg {
2539 1.1 mrg gfc_se se;
2540 1.1 mrg
2541 1.1 mrg gfc_init_se (&se, NULL);
2542 1.1 mrg
2543 1.1 mrg if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2544 1.1 mrg return;
2545 1.1 mrg
2546 1.1 mrg /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2547 1.1 mrg "flatten" array constructors by taking their first element; all elements
2548 1.1 mrg should be the same length or a cl->length should be present. */
2549 1.1 mrg if (!cl->length)
2550 1.1 mrg {
2551 1.1 mrg gfc_expr* expr_flat;
2552 1.1 mrg if (!expr)
2553 1.1 mrg return;
2554 1.1 mrg expr_flat = gfc_copy_expr (expr);
2555 1.1 mrg flatten_array_ctors_without_strlen (expr_flat);
2556 1.1 mrg gfc_resolve_expr (expr_flat);
2557 1.1 mrg
2558 1.1 mrg gfc_conv_expr (&se, expr_flat);
2559 1.1 mrg gfc_add_block_to_block (pblock, &se.pre);
2560 1.1 mrg cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2561 1.1 mrg
2562 1.1 mrg gfc_free_expr (expr_flat);
2563 1.1 mrg return;
2564 1.1 mrg }
2565 1.1 mrg
2566 1.1 mrg /* Convert cl->length. */
2567 1.1 mrg
2568 1.1 mrg gcc_assert (cl->length);
2569 1.1 mrg
2570 1.1 mrg gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2571 1.1 mrg se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2572 1.1 mrg se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2573 1.1 mrg gfc_add_block_to_block (pblock, &se.pre);
2574 1.1 mrg
2575 1.1 mrg if (cl->backend_decl && VAR_P (cl->backend_decl))
2576 1.1 mrg gfc_add_modify (pblock, cl->backend_decl, se.expr);
2577 1.1 mrg else
2578 1.1 mrg cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2579 1.1 mrg }
2580 1.1 mrg
2581 1.1 mrg
2582 1.1 mrg static void
2583 1.1 mrg gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2584 1.1 mrg const char *name, locus *where)
2585 1.1 mrg {
2586 1.1 mrg tree tmp;
2587 1.1 mrg tree type;
2588 1.1 mrg tree fault;
2589 1.1 mrg gfc_se start;
2590 1.1 mrg gfc_se end;
2591 1.1 mrg char *msg;
2592 1.1 mrg mpz_t length;
2593 1.1 mrg
2594 1.1 mrg type = gfc_get_character_type (kind, ref->u.ss.length);
2595 1.1 mrg type = build_pointer_type (type);
2596 1.1 mrg
2597 1.1 mrg gfc_init_se (&start, se);
2598 1.1 mrg gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2599 1.1 mrg gfc_add_block_to_block (&se->pre, &start.pre);
2600 1.1 mrg
2601 1.1 mrg if (integer_onep (start.expr))
2602 1.1 mrg gfc_conv_string_parameter (se);
2603 1.1 mrg else
2604 1.1 mrg {
2605 1.1 mrg tmp = start.expr;
2606 1.1 mrg STRIP_NOPS (tmp);
2607 1.1 mrg /* Avoid multiple evaluation of substring start. */
2608 1.1 mrg if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2609 1.1 mrg start.expr = gfc_evaluate_now (start.expr, &se->pre);
2610 1.1 mrg
2611 1.1 mrg /* Change the start of the string. */
2612 1.1 mrg if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
2613 1.1 mrg || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
2614 1.1 mrg && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2615 1.1 mrg tmp = se->expr;
2616 1.1 mrg else
2617 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
2618 1.1 mrg se->expr);
2619 1.1 mrg /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2620 1.1 mrg if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2621 1.1 mrg {
2622 1.1 mrg tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true);
2623 1.1 mrg se->expr = gfc_build_addr_expr (type, tmp);
2624 1.1 mrg }
2625 1.1 mrg }
2626 1.1 mrg
2627 1.1 mrg /* Length = end + 1 - start. */
2628 1.1 mrg gfc_init_se (&end, se);
2629 1.1 mrg if (ref->u.ss.end == NULL)
2630 1.1 mrg end.expr = se->string_length;
2631 1.1 mrg else
2632 1.1 mrg {
2633 1.1 mrg gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2634 1.1 mrg gfc_add_block_to_block (&se->pre, &end.pre);
2635 1.1 mrg }
2636 1.1 mrg tmp = end.expr;
2637 1.1 mrg STRIP_NOPS (tmp);
2638 1.1 mrg if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2639 1.1 mrg end.expr = gfc_evaluate_now (end.expr, &se->pre);
2640 1.1 mrg
2641 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2642 1.1 mrg && (ref->u.ss.start->symtree
2643 1.1 mrg && !ref->u.ss.start->symtree->n.sym->attr.implied_index))
2644 1.1 mrg {
2645 1.1 mrg tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2646 1.1 mrg logical_type_node, start.expr,
2647 1.1 mrg end.expr);
2648 1.1 mrg
2649 1.1 mrg /* Check lower bound. */
2650 1.1 mrg fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2651 1.1 mrg start.expr,
2652 1.1 mrg build_one_cst (TREE_TYPE (start.expr)));
2653 1.1 mrg fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2654 1.1 mrg logical_type_node, nonempty, fault);
2655 1.1 mrg if (name)
2656 1.1 mrg msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2657 1.1 mrg "is less than one", name);
2658 1.1 mrg else
2659 1.1 mrg msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2660 1.1 mrg "is less than one");
2661 1.1 mrg gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2662 1.1 mrg fold_convert (long_integer_type_node,
2663 1.1 mrg start.expr));
2664 1.1 mrg free (msg);
2665 1.1 mrg
2666 1.1 mrg /* Check upper bound. */
2667 1.1 mrg fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2668 1.1 mrg end.expr, se->string_length);
2669 1.1 mrg fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2670 1.1 mrg logical_type_node, nonempty, fault);
2671 1.1 mrg if (name)
2672 1.1 mrg msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2673 1.1 mrg "exceeds string length (%%ld)", name);
2674 1.1 mrg else
2675 1.1 mrg msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2676 1.1 mrg "exceeds string length (%%ld)");
2677 1.1 mrg gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2678 1.1 mrg fold_convert (long_integer_type_node, end.expr),
2679 1.1 mrg fold_convert (long_integer_type_node,
2680 1.1 mrg se->string_length));
2681 1.1 mrg free (msg);
2682 1.1 mrg }
2683 1.1 mrg
2684 1.1 mrg /* Try to calculate the length from the start and end expressions. */
2685 1.1 mrg if (ref->u.ss.end
2686 1.1 mrg && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2687 1.1 mrg {
2688 1.1 mrg HOST_WIDE_INT i_len;
2689 1.1 mrg
2690 1.1 mrg i_len = gfc_mpz_get_hwi (length) + 1;
2691 1.1 mrg if (i_len < 0)
2692 1.1 mrg i_len = 0;
2693 1.1 mrg
2694 1.1 mrg tmp = build_int_cst (gfc_charlen_type_node, i_len);
2695 1.1 mrg mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2696 1.1 mrg }
2697 1.1 mrg else
2698 1.1 mrg {
2699 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2700 1.1 mrg fold_convert (gfc_charlen_type_node, end.expr),
2701 1.1 mrg fold_convert (gfc_charlen_type_node, start.expr));
2702 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2703 1.1 mrg build_int_cst (gfc_charlen_type_node, 1), tmp);
2704 1.1 mrg tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2705 1.1 mrg tmp, build_int_cst (gfc_charlen_type_node, 0));
2706 1.1 mrg }
2707 1.1 mrg
2708 1.1 mrg se->string_length = tmp;
2709 1.1 mrg }
2710 1.1 mrg
2711 1.1 mrg
2712 1.1 mrg /* Convert a derived type component reference. */
2713 1.1 mrg
2714 1.1 mrg void
2715 1.1 mrg gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2716 1.1 mrg {
2717 1.1 mrg gfc_component *c;
2718 1.1 mrg tree tmp;
2719 1.1 mrg tree decl;
2720 1.1 mrg tree field;
2721 1.1 mrg tree context;
2722 1.1 mrg
2723 1.1 mrg c = ref->u.c.component;
2724 1.1 mrg
2725 1.1 mrg if (c->backend_decl == NULL_TREE
2726 1.1 mrg && ref->u.c.sym != NULL)
2727 1.1 mrg gfc_get_derived_type (ref->u.c.sym);
2728 1.1 mrg
2729 1.1 mrg field = c->backend_decl;
2730 1.1 mrg gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2731 1.1 mrg decl = se->expr;
2732 1.1 mrg context = DECL_FIELD_CONTEXT (field);
2733 1.1 mrg
2734 1.1 mrg /* Components can correspond to fields of different containing
2735 1.1 mrg types, as components are created without context, whereas
2736 1.1 mrg a concrete use of a component has the type of decl as context.
2737 1.1 mrg So, if the type doesn't match, we search the corresponding
2738 1.1 mrg FIELD_DECL in the parent type. To not waste too much time
2739 1.1 mrg we cache this result in norestrict_decl.
2740 1.1 mrg On the other hand, if the context is a UNION or a MAP (a
2741 1.1 mrg RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2742 1.1 mrg
2743 1.1 mrg if (context != TREE_TYPE (decl)
2744 1.1 mrg && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2745 1.1 mrg || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2746 1.1 mrg {
2747 1.1 mrg tree f2 = c->norestrict_decl;
2748 1.1 mrg if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2749 1.1 mrg for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2750 1.1 mrg if (TREE_CODE (f2) == FIELD_DECL
2751 1.1 mrg && DECL_NAME (f2) == DECL_NAME (field))
2752 1.1 mrg break;
2753 1.1 mrg gcc_assert (f2);
2754 1.1 mrg c->norestrict_decl = f2;
2755 1.1 mrg field = f2;
2756 1.1 mrg }
2757 1.1 mrg
2758 1.1 mrg if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2759 1.1 mrg && strcmp ("_data", c->name) == 0)
2760 1.1 mrg {
2761 1.1 mrg /* Found a ref to the _data component. Store the associated ref to
2762 1.1 mrg the vptr in se->class_vptr. */
2763 1.1 mrg se->class_vptr = gfc_class_vptr_get (decl);
2764 1.1 mrg }
2765 1.1 mrg else
2766 1.1 mrg se->class_vptr = NULL_TREE;
2767 1.1 mrg
2768 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2769 1.1 mrg decl, field, NULL_TREE);
2770 1.1 mrg
2771 1.1 mrg se->expr = tmp;
2772 1.1 mrg
2773 1.1 mrg /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2774 1.1 mrg strlen () conditional below. */
2775 1.1 mrg if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2776 1.1 mrg && !c->ts.deferred
2777 1.1 mrg && !c->attr.pdt_string)
2778 1.1 mrg {
2779 1.1 mrg tmp = c->ts.u.cl->backend_decl;
2780 1.1 mrg /* Components must always be constant length. */
2781 1.1 mrg gcc_assert (tmp && INTEGER_CST_P (tmp));
2782 1.1 mrg se->string_length = tmp;
2783 1.1 mrg }
2784 1.1 mrg
2785 1.1 mrg if (gfc_deferred_strlen (c, &field))
2786 1.1 mrg {
2787 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF,
2788 1.1 mrg TREE_TYPE (field),
2789 1.1 mrg decl, field, NULL_TREE);
2790 1.1 mrg se->string_length = tmp;
2791 1.1 mrg }
2792 1.1 mrg
2793 1.1 mrg if (((c->attr.pointer || c->attr.allocatable)
2794 1.1 mrg && (!c->attr.dimension && !c->attr.codimension)
2795 1.1 mrg && c->ts.type != BT_CHARACTER)
2796 1.1 mrg || c->attr.proc_pointer)
2797 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location,
2798 1.1 mrg se->expr);
2799 1.1 mrg }
2800 1.1 mrg
2801 1.1 mrg
2802 1.1 mrg /* This function deals with component references to components of the
2803 1.1 mrg parent type for derived type extensions. */
2804 1.1 mrg void
2805 1.1 mrg conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2806 1.1 mrg {
2807 1.1 mrg gfc_component *c;
2808 1.1 mrg gfc_component *cmp;
2809 1.1 mrg gfc_symbol *dt;
2810 1.1 mrg gfc_ref parent;
2811 1.1 mrg
2812 1.1 mrg dt = ref->u.c.sym;
2813 1.1 mrg c = ref->u.c.component;
2814 1.1 mrg
2815 1.1 mrg /* Return if the component is in this type, i.e. not in the parent type. */
2816 1.1 mrg for (cmp = dt->components; cmp; cmp = cmp->next)
2817 1.1 mrg if (c == cmp)
2818 1.1 mrg return;
2819 1.1 mrg
2820 1.1 mrg /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2821 1.1 mrg parent.type = REF_COMPONENT;
2822 1.1 mrg parent.next = NULL;
2823 1.1 mrg parent.u.c.sym = dt;
2824 1.1 mrg parent.u.c.component = dt->components;
2825 1.1 mrg
2826 1.1 mrg if (dt->backend_decl == NULL)
2827 1.1 mrg gfc_get_derived_type (dt);
2828 1.1 mrg
2829 1.1 mrg /* Build the reference and call self. */
2830 1.1 mrg gfc_conv_component_ref (se, &parent);
2831 1.1 mrg parent.u.c.sym = dt->components->ts.u.derived;
2832 1.1 mrg parent.u.c.component = c;
2833 1.1 mrg conv_parent_component_references (se, &parent);
2834 1.1 mrg }
2835 1.1 mrg
2836 1.1 mrg
2837 1.1 mrg static void
2838 1.1 mrg conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2839 1.1 mrg {
2840 1.1 mrg tree res = se->expr;
2841 1.1 mrg
2842 1.1 mrg switch (ref->u.i)
2843 1.1 mrg {
2844 1.1 mrg case INQUIRY_RE:
2845 1.1 mrg res = fold_build1_loc (input_location, REALPART_EXPR,
2846 1.1 mrg TREE_TYPE (TREE_TYPE (res)), res);
2847 1.1 mrg break;
2848 1.1 mrg
2849 1.1 mrg case INQUIRY_IM:
2850 1.1 mrg res = fold_build1_loc (input_location, IMAGPART_EXPR,
2851 1.1 mrg TREE_TYPE (TREE_TYPE (res)), res);
2852 1.1 mrg break;
2853 1.1 mrg
2854 1.1 mrg case INQUIRY_KIND:
2855 1.1 mrg res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2856 1.1 mrg ts->kind);
2857 1.1 mrg se->string_length = NULL_TREE;
2858 1.1 mrg break;
2859 1.1 mrg
2860 1.1 mrg case INQUIRY_LEN:
2861 1.1 mrg res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2862 1.1 mrg se->string_length);
2863 1.1 mrg se->string_length = NULL_TREE;
2864 1.1 mrg break;
2865 1.1 mrg
2866 1.1 mrg default:
2867 1.1 mrg gcc_unreachable ();
2868 1.1 mrg }
2869 1.1 mrg se->expr = res;
2870 1.1 mrg }
2871 1.1 mrg
2872 1.1 mrg /* Dereference VAR where needed if it is a pointer, reference, etc.
2873 1.1 mrg according to Fortran semantics. */
2874 1.1 mrg
2875 1.1 mrg tree
2876 1.1 mrg gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2877 1.1 mrg bool is_classarray)
2878 1.1 mrg {
2879 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (var)))
2880 1.1 mrg return var;
2881 1.1 mrg if (is_CFI_desc (sym, NULL))
2882 1.1 mrg return build_fold_indirect_ref_loc (input_location, var);
2883 1.1 mrg
2884 1.1 mrg /* Characters are entirely different from other types, they are treated
2885 1.1 mrg separately. */
2886 1.1 mrg if (sym->ts.type == BT_CHARACTER)
2887 1.1 mrg {
2888 1.1 mrg /* Dereference character pointer dummy arguments
2889 1.1 mrg or results. */
2890 1.1 mrg if ((sym->attr.pointer || sym->attr.allocatable
2891 1.1 mrg || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2892 1.1 mrg && (sym->attr.dummy
2893 1.1 mrg || sym->attr.function
2894 1.1 mrg || sym->attr.result))
2895 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2896 1.1 mrg }
2897 1.1 mrg else if (!sym->attr.value)
2898 1.1 mrg {
2899 1.1 mrg /* Dereference temporaries for class array dummy arguments. */
2900 1.1 mrg if (sym->attr.dummy && is_classarray
2901 1.1 mrg && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2902 1.1 mrg {
2903 1.1 mrg if (!descriptor_only_p)
2904 1.1 mrg var = GFC_DECL_SAVED_DESCRIPTOR (var);
2905 1.1 mrg
2906 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2907 1.1 mrg }
2908 1.1 mrg
2909 1.1 mrg /* Dereference non-character scalar dummy arguments. */
2910 1.1 mrg if (sym->attr.dummy && !sym->attr.dimension
2911 1.1 mrg && !(sym->attr.codimension && sym->attr.allocatable)
2912 1.1 mrg && (sym->ts.type != BT_CLASS
2913 1.1 mrg || (!CLASS_DATA (sym)->attr.dimension
2914 1.1 mrg && !(CLASS_DATA (sym)->attr.codimension
2915 1.1 mrg && CLASS_DATA (sym)->attr.allocatable))))
2916 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2917 1.1 mrg
2918 1.1 mrg /* Dereference scalar hidden result. */
2919 1.1 mrg if (flag_f2c && sym->ts.type == BT_COMPLEX
2920 1.1 mrg && (sym->attr.function || sym->attr.result)
2921 1.1 mrg && !sym->attr.dimension && !sym->attr.pointer
2922 1.1 mrg && !sym->attr.always_explicit)
2923 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2924 1.1 mrg
2925 1.1 mrg /* Dereference non-character, non-class pointer variables.
2926 1.1 mrg These must be dummies, results, or scalars. */
2927 1.1 mrg if (!is_classarray
2928 1.1 mrg && (sym->attr.pointer || sym->attr.allocatable
2929 1.1 mrg || gfc_is_associate_pointer (sym)
2930 1.1 mrg || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2931 1.1 mrg && (sym->attr.dummy
2932 1.1 mrg || sym->attr.function
2933 1.1 mrg || sym->attr.result
2934 1.1 mrg || (!sym->attr.dimension
2935 1.1 mrg && (!sym->attr.codimension || !sym->attr.allocatable))))
2936 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2937 1.1 mrg /* Now treat the class array pointer variables accordingly. */
2938 1.1 mrg else if (sym->ts.type == BT_CLASS
2939 1.1 mrg && sym->attr.dummy
2940 1.1 mrg && (CLASS_DATA (sym)->attr.dimension
2941 1.1 mrg || CLASS_DATA (sym)->attr.codimension)
2942 1.1 mrg && ((CLASS_DATA (sym)->as
2943 1.1 mrg && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2944 1.1 mrg || CLASS_DATA (sym)->attr.allocatable
2945 1.1 mrg || CLASS_DATA (sym)->attr.class_pointer))
2946 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2947 1.1 mrg /* And the case where a non-dummy, non-result, non-function,
2948 1.1 mrg non-allocable and non-pointer classarray is present. This case was
2949 1.1 mrg previously covered by the first if, but with introducing the
2950 1.1 mrg condition !is_classarray there, that case has to be covered
2951 1.1 mrg explicitly. */
2952 1.1 mrg else if (sym->ts.type == BT_CLASS
2953 1.1 mrg && !sym->attr.dummy
2954 1.1 mrg && !sym->attr.function
2955 1.1 mrg && !sym->attr.result
2956 1.1 mrg && (CLASS_DATA (sym)->attr.dimension
2957 1.1 mrg || CLASS_DATA (sym)->attr.codimension)
2958 1.1 mrg && (sym->assoc
2959 1.1 mrg || !CLASS_DATA (sym)->attr.allocatable)
2960 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer)
2961 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var);
2962 1.1 mrg }
2963 1.1 mrg
2964 1.1 mrg return var;
2965 1.1 mrg }
2966 1.1 mrg
2967 1.1 mrg /* Return the contents of a variable. Also handles reference/pointer
2968 1.1 mrg variables (all Fortran pointer references are implicit). */
2969 1.1 mrg
2970 1.1 mrg static void
2971 1.1 mrg gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2972 1.1 mrg {
2973 1.1 mrg gfc_ss *ss;
2974 1.1 mrg gfc_ref *ref;
2975 1.1 mrg gfc_symbol *sym;
2976 1.1 mrg tree parent_decl = NULL_TREE;
2977 1.1 mrg int parent_flag;
2978 1.1 mrg bool return_value;
2979 1.1 mrg bool alternate_entry;
2980 1.1 mrg bool entry_master;
2981 1.1 mrg bool is_classarray;
2982 1.1 mrg bool first_time = true;
2983 1.1 mrg
2984 1.1 mrg sym = expr->symtree->n.sym;
2985 1.1 mrg is_classarray = IS_CLASS_ARRAY (sym);
2986 1.1 mrg ss = se->ss;
2987 1.1 mrg if (ss != NULL)
2988 1.1 mrg {
2989 1.1 mrg gfc_ss_info *ss_info = ss->info;
2990 1.1 mrg
2991 1.1 mrg /* Check that something hasn't gone horribly wrong. */
2992 1.1 mrg gcc_assert (ss != gfc_ss_terminator);
2993 1.1 mrg gcc_assert (ss_info->expr == expr);
2994 1.1 mrg
2995 1.1 mrg /* A scalarized term. We already know the descriptor. */
2996 1.1 mrg se->expr = ss_info->data.array.descriptor;
2997 1.1 mrg se->string_length = ss_info->string_length;
2998 1.1 mrg ref = ss_info->data.array.ref;
2999 1.1 mrg if (ref)
3000 1.1 mrg gcc_assert (ref->type == REF_ARRAY
3001 1.1 mrg && ref->u.ar.type != AR_ELEMENT);
3002 1.1 mrg else
3003 1.1 mrg gfc_conv_tmp_array_ref (se);
3004 1.1 mrg }
3005 1.1 mrg else
3006 1.1 mrg {
3007 1.1 mrg tree se_expr = NULL_TREE;
3008 1.1 mrg
3009 1.1 mrg se->expr = gfc_get_symbol_decl (sym);
3010 1.1 mrg
3011 1.1 mrg /* Deal with references to a parent results or entries by storing
3012 1.1 mrg the current_function_decl and moving to the parent_decl. */
3013 1.1 mrg return_value = sym->attr.function && sym->result == sym;
3014 1.1 mrg alternate_entry = sym->attr.function && sym->attr.entry
3015 1.1 mrg && sym->result == sym;
3016 1.1 mrg entry_master = sym->attr.result
3017 1.1 mrg && sym->ns->proc_name->attr.entry_master
3018 1.1 mrg && !gfc_return_by_reference (sym->ns->proc_name);
3019 1.1 mrg if (current_function_decl)
3020 1.1 mrg parent_decl = DECL_CONTEXT (current_function_decl);
3021 1.1 mrg
3022 1.1 mrg if ((se->expr == parent_decl && return_value)
3023 1.1 mrg || (sym->ns && sym->ns->proc_name
3024 1.1 mrg && parent_decl
3025 1.1 mrg && sym->ns->proc_name->backend_decl == parent_decl
3026 1.1 mrg && (alternate_entry || entry_master)))
3027 1.1 mrg parent_flag = 1;
3028 1.1 mrg else
3029 1.1 mrg parent_flag = 0;
3030 1.1 mrg
3031 1.1 mrg /* Special case for assigning the return value of a function.
3032 1.1 mrg Self recursive functions must have an explicit return value. */
3033 1.1 mrg if (return_value && (se->expr == current_function_decl || parent_flag))
3034 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3035 1.1 mrg
3036 1.1 mrg /* Similarly for alternate entry points. */
3037 1.1 mrg else if (alternate_entry
3038 1.1 mrg && (sym->ns->proc_name->backend_decl == current_function_decl
3039 1.1 mrg || parent_flag))
3040 1.1 mrg {
3041 1.1 mrg gfc_entry_list *el = NULL;
3042 1.1 mrg
3043 1.1 mrg for (el = sym->ns->entries; el; el = el->next)
3044 1.1 mrg if (sym == el->sym)
3045 1.1 mrg {
3046 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3047 1.1 mrg break;
3048 1.1 mrg }
3049 1.1 mrg }
3050 1.1 mrg
3051 1.1 mrg else if (entry_master
3052 1.1 mrg && (sym->ns->proc_name->backend_decl == current_function_decl
3053 1.1 mrg || parent_flag))
3054 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3055 1.1 mrg
3056 1.1 mrg if (se_expr)
3057 1.1 mrg se->expr = se_expr;
3058 1.1 mrg
3059 1.1 mrg /* Procedure actual arguments. Look out for temporary variables
3060 1.1 mrg with the same attributes as function values. */
3061 1.1 mrg else if (!sym->attr.temporary
3062 1.1 mrg && sym->attr.flavor == FL_PROCEDURE
3063 1.1 mrg && se->expr != current_function_decl)
3064 1.1 mrg {
3065 1.1 mrg if (!sym->attr.dummy && !sym->attr.proc_pointer)
3066 1.1 mrg {
3067 1.1 mrg gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
3068 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3069 1.1 mrg }
3070 1.1 mrg return;
3071 1.1 mrg }
3072 1.1 mrg
3073 1.1 mrg /* Dereference the expression, where needed. */
3074 1.1 mrg se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3075 1.1 mrg is_classarray);
3076 1.1 mrg
3077 1.1 mrg ref = expr->ref;
3078 1.1 mrg }
3079 1.1 mrg
3080 1.1 mrg /* For character variables, also get the length. */
3081 1.1 mrg if (sym->ts.type == BT_CHARACTER)
3082 1.1 mrg {
3083 1.1 mrg /* If the character length of an entry isn't set, get the length from
3084 1.1 mrg the master function instead. */
3085 1.1 mrg if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3086 1.1 mrg se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
3087 1.1 mrg else
3088 1.1 mrg se->string_length = sym->ts.u.cl->backend_decl;
3089 1.1 mrg gcc_assert (se->string_length);
3090 1.1 mrg }
3091 1.1 mrg
3092 1.1 mrg gfc_typespec *ts = &sym->ts;
3093 1.1 mrg while (ref)
3094 1.1 mrg {
3095 1.1 mrg switch (ref->type)
3096 1.1 mrg {
3097 1.1 mrg case REF_ARRAY:
3098 1.1 mrg /* Return the descriptor if that's what we want and this is an array
3099 1.1 mrg section reference. */
3100 1.1 mrg if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3101 1.1 mrg return;
3102 1.1 mrg /* TODO: Pointers to single elements of array sections, eg elemental subs. */
3103 1.1 mrg /* Return the descriptor for array pointers and allocations. */
3104 1.1 mrg if (se->want_pointer
3105 1.1 mrg && ref->next == NULL && (se->descriptor_only))
3106 1.1 mrg return;
3107 1.1 mrg
3108 1.1 mrg gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
3109 1.1 mrg /* Return a pointer to an element. */
3110 1.1 mrg break;
3111 1.1 mrg
3112 1.1 mrg case REF_COMPONENT:
3113 1.1 mrg ts = &ref->u.c.component->ts;
3114 1.1 mrg if (first_time && is_classarray && sym->attr.dummy
3115 1.1 mrg && se->descriptor_only
3116 1.1 mrg && !CLASS_DATA (sym)->attr.allocatable
3117 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer
3118 1.1 mrg && CLASS_DATA (sym)->as
3119 1.1 mrg && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3120 1.1 mrg && strcmp ("_data", ref->u.c.component->name) == 0)
3121 1.1 mrg /* Skip the first ref of a _data component, because for class
3122 1.1 mrg arrays that one is already done by introducing a temporary
3123 1.1 mrg array descriptor. */
3124 1.1 mrg break;
3125 1.1 mrg
3126 1.1 mrg if (ref->u.c.sym->attr.extension)
3127 1.1 mrg conv_parent_component_references (se, ref);
3128 1.1 mrg
3129 1.1 mrg gfc_conv_component_ref (se, ref);
3130 1.1 mrg if (!ref->next && ref->u.c.sym->attr.codimension
3131 1.1 mrg && se->want_pointer && se->descriptor_only)
3132 1.1 mrg return;
3133 1.1 mrg
3134 1.1 mrg break;
3135 1.1 mrg
3136 1.1 mrg case REF_SUBSTRING:
3137 1.1 mrg gfc_conv_substring (se, ref, expr->ts.kind,
3138 1.1 mrg expr->symtree->name, &expr->where);
3139 1.1 mrg break;
3140 1.1 mrg
3141 1.1 mrg case REF_INQUIRY:
3142 1.1 mrg conv_inquiry (se, ref, expr, ts);
3143 1.1 mrg break;
3144 1.1 mrg
3145 1.1 mrg default:
3146 1.1 mrg gcc_unreachable ();
3147 1.1 mrg break;
3148 1.1 mrg }
3149 1.1 mrg first_time = false;
3150 1.1 mrg ref = ref->next;
3151 1.1 mrg }
3152 1.1 mrg /* Pointer assignment, allocation or pass by reference. Arrays are handled
3153 1.1 mrg separately. */
3154 1.1 mrg if (se->want_pointer)
3155 1.1 mrg {
3156 1.1 mrg if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
3157 1.1 mrg gfc_conv_string_parameter (se);
3158 1.1 mrg else
3159 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3160 1.1 mrg }
3161 1.1 mrg }
3162 1.1 mrg
3163 1.1 mrg
3164 1.1 mrg /* Unary ops are easy... Or they would be if ! was a valid op. */
3165 1.1 mrg
3166 1.1 mrg static void
3167 1.1 mrg gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3168 1.1 mrg {
3169 1.1 mrg gfc_se operand;
3170 1.1 mrg tree type;
3171 1.1 mrg
3172 1.1 mrg gcc_assert (expr->ts.type != BT_CHARACTER);
3173 1.1 mrg /* Initialize the operand. */
3174 1.1 mrg gfc_init_se (&operand, se);
3175 1.1 mrg gfc_conv_expr_val (&operand, expr->value.op.op1);
3176 1.1 mrg gfc_add_block_to_block (&se->pre, &operand.pre);
3177 1.1 mrg
3178 1.1 mrg type = gfc_typenode_for_spec (&expr->ts);
3179 1.1 mrg
3180 1.1 mrg /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3181 1.1 mrg We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3182 1.1 mrg All other unary operators have an equivalent GIMPLE unary operator. */
3183 1.1 mrg if (code == TRUTH_NOT_EXPR)
3184 1.1 mrg se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3185 1.1 mrg build_int_cst (type, 0));
3186 1.1 mrg else
3187 1.1 mrg se->expr = fold_build1_loc (input_location, code, type, operand.expr);
3188 1.1 mrg
3189 1.1 mrg }
3190 1.1 mrg
3191 1.1 mrg /* Expand power operator to optimal multiplications when a value is raised
3192 1.1 mrg to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3193 1.1 mrg Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3194 1.1 mrg Programming", 3rd Edition, 1998. */
3195 1.1 mrg
3196 1.1 mrg /* This code is mostly duplicated from expand_powi in the backend.
3197 1.1 mrg We establish the "optimal power tree" lookup table with the defined size.
3198 1.1 mrg The items in the table are the exponents used to calculate the index
3199 1.1 mrg exponents. Any integer n less than the value can get an "addition chain",
3200 1.1 mrg with the first node being one. */
3201 1.1 mrg #define POWI_TABLE_SIZE 256
3202 1.1 mrg
3203 1.1 mrg /* The table is from builtins.cc. */
3204 1.1 mrg static const unsigned char powi_table[POWI_TABLE_SIZE] =
3205 1.1 mrg {
3206 1.1 mrg 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3207 1.1 mrg 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3208 1.1 mrg 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3209 1.1 mrg 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3210 1.1 mrg 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3211 1.1 mrg 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3212 1.1 mrg 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3213 1.1 mrg 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3214 1.1 mrg 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3215 1.1 mrg 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3216 1.1 mrg 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3217 1.1 mrg 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3218 1.1 mrg 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3219 1.1 mrg 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3220 1.1 mrg 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3221 1.1 mrg 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3222 1.1 mrg 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3223 1.1 mrg 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3224 1.1 mrg 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3225 1.1 mrg 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3226 1.1 mrg 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3227 1.1 mrg 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3228 1.1 mrg 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3229 1.1 mrg 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3230 1.1 mrg 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3231 1.1 mrg 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3232 1.1 mrg 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3233 1.1 mrg 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3234 1.1 mrg 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3235 1.1 mrg 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3236 1.1 mrg 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3237 1.1 mrg 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3238 1.1 mrg };
3239 1.1 mrg
3240 1.1 mrg /* If n is larger than lookup table's max index, we use the "window
3241 1.1 mrg method". */
3242 1.1 mrg #define POWI_WINDOW_SIZE 3
3243 1.1 mrg
3244 1.1 mrg /* Recursive function to expand the power operator. The temporary
3245 1.1 mrg values are put in tmpvar. The function returns tmpvar[1] ** n. */
3246 1.1 mrg static tree
3247 1.1 mrg gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
3248 1.1 mrg {
3249 1.1 mrg tree op0;
3250 1.1 mrg tree op1;
3251 1.1 mrg tree tmp;
3252 1.1 mrg int digit;
3253 1.1 mrg
3254 1.1 mrg if (n < POWI_TABLE_SIZE)
3255 1.1 mrg {
3256 1.1 mrg if (tmpvar[n])
3257 1.1 mrg return tmpvar[n];
3258 1.1 mrg
3259 1.1 mrg op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3260 1.1 mrg op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3261 1.1 mrg }
3262 1.1 mrg else if (n & 1)
3263 1.1 mrg {
3264 1.1 mrg digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3265 1.1 mrg op0 = gfc_conv_powi (se, n - digit, tmpvar);
3266 1.1 mrg op1 = gfc_conv_powi (se, digit, tmpvar);
3267 1.1 mrg }
3268 1.1 mrg else
3269 1.1 mrg {
3270 1.1 mrg op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3271 1.1 mrg op1 = op0;
3272 1.1 mrg }
3273 1.1 mrg
3274 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
3275 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre);
3276 1.1 mrg
3277 1.1 mrg if (n < POWI_TABLE_SIZE)
3278 1.1 mrg tmpvar[n] = tmp;
3279 1.1 mrg
3280 1.1 mrg return tmp;
3281 1.1 mrg }
3282 1.1 mrg
3283 1.1 mrg
3284 1.1 mrg /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3285 1.1 mrg return 1. Else return 0 and a call to runtime library functions
3286 1.1 mrg will have to be built. */
3287 1.1 mrg static int
3288 1.1 mrg gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3289 1.1 mrg {
3290 1.1 mrg tree cond;
3291 1.1 mrg tree tmp;
3292 1.1 mrg tree type;
3293 1.1 mrg tree vartmp[POWI_TABLE_SIZE];
3294 1.1 mrg HOST_WIDE_INT m;
3295 1.1 mrg unsigned HOST_WIDE_INT n;
3296 1.1 mrg int sgn;
3297 1.1 mrg wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
3298 1.1 mrg
3299 1.1 mrg /* If exponent is too large, we won't expand it anyway, so don't bother
3300 1.1 mrg with large integer values. */
3301 1.1 mrg if (!wi::fits_shwi_p (wrhs))
3302 1.1 mrg return 0;
3303 1.1 mrg
3304 1.1 mrg m = wrhs.to_shwi ();
3305 1.1 mrg /* Use the wide_int's routine to reliably get the absolute value on all
3306 1.1 mrg platforms. Then convert it to a HOST_WIDE_INT like above. */
3307 1.1 mrg n = wi::abs (wrhs).to_shwi ();
3308 1.1 mrg
3309 1.1 mrg type = TREE_TYPE (lhs);
3310 1.1 mrg sgn = tree_int_cst_sgn (rhs);
3311 1.1 mrg
3312 1.1 mrg if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3313 1.1 mrg || optimize_size) && (m > 2 || m < -1))
3314 1.1 mrg return 0;
3315 1.1 mrg
3316 1.1 mrg /* rhs == 0 */
3317 1.1 mrg if (sgn == 0)
3318 1.1 mrg {
3319 1.1 mrg se->expr = gfc_build_const (type, integer_one_node);
3320 1.1 mrg return 1;
3321 1.1 mrg }
3322 1.1 mrg
3323 1.1 mrg /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3324 1.1 mrg if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3325 1.1 mrg {
3326 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3327 1.1 mrg lhs, build_int_cst (TREE_TYPE (lhs), -1));
3328 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3329 1.1 mrg lhs, build_int_cst (TREE_TYPE (lhs), 1));
3330 1.1 mrg
3331 1.1 mrg /* If rhs is even,
3332 1.1 mrg result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3333 1.1 mrg if ((n & 1) == 0)
3334 1.1 mrg {
3335 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3336 1.1 mrg logical_type_node, tmp, cond);
3337 1.1 mrg se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3338 1.1 mrg tmp, build_int_cst (type, 1),
3339 1.1 mrg build_int_cst (type, 0));
3340 1.1 mrg return 1;
3341 1.1 mrg }
3342 1.1 mrg /* If rhs is odd,
3343 1.1 mrg result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3344 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3345 1.1 mrg build_int_cst (type, -1),
3346 1.1 mrg build_int_cst (type, 0));
3347 1.1 mrg se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3348 1.1 mrg cond, build_int_cst (type, 1), tmp);
3349 1.1 mrg return 1;
3350 1.1 mrg }
3351 1.1 mrg
3352 1.1 mrg memset (vartmp, 0, sizeof (vartmp));
3353 1.1 mrg vartmp[1] = lhs;
3354 1.1 mrg if (sgn == -1)
3355 1.1 mrg {
3356 1.1 mrg tmp = gfc_build_const (type, integer_one_node);
3357 1.1 mrg vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3358 1.1 mrg vartmp[1]);
3359 1.1 mrg }
3360 1.1 mrg
3361 1.1 mrg se->expr = gfc_conv_powi (se, n, vartmp);
3362 1.1 mrg
3363 1.1 mrg return 1;
3364 1.1 mrg }
3365 1.1 mrg
3366 1.1 mrg
3367 1.1 mrg /* Power op (**). Constant integer exponent has special handling. */
3368 1.1 mrg
3369 1.1 mrg static void
3370 1.1 mrg gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3371 1.1 mrg {
3372 1.1 mrg tree gfc_int4_type_node;
3373 1.1 mrg int kind;
3374 1.1 mrg int ikind;
3375 1.1 mrg int res_ikind_1, res_ikind_2;
3376 1.1 mrg gfc_se lse;
3377 1.1 mrg gfc_se rse;
3378 1.1 mrg tree fndecl = NULL;
3379 1.1 mrg
3380 1.1 mrg gfc_init_se (&lse, se);
3381 1.1 mrg gfc_conv_expr_val (&lse, expr->value.op.op1);
3382 1.1 mrg lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3383 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre);
3384 1.1 mrg
3385 1.1 mrg gfc_init_se (&rse, se);
3386 1.1 mrg gfc_conv_expr_val (&rse, expr->value.op.op2);
3387 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre);
3388 1.1 mrg
3389 1.1 mrg if (expr->value.op.op2->ts.type == BT_INTEGER
3390 1.1 mrg && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3391 1.1 mrg if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3392 1.1 mrg return;
3393 1.1 mrg
3394 1.1 mrg if (INTEGER_CST_P (lse.expr)
3395 1.1 mrg && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3396 1.1 mrg {
3397 1.1 mrg wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3398 1.1 mrg HOST_WIDE_INT v, w;
3399 1.1 mrg int kind, ikind, bit_size;
3400 1.1 mrg
3401 1.1 mrg v = wlhs.to_shwi ();
3402 1.1 mrg w = abs (v);
3403 1.1 mrg
3404 1.1 mrg kind = expr->value.op.op1->ts.kind;
3405 1.1 mrg ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3406 1.1 mrg bit_size = gfc_integer_kinds[ikind].bit_size;
3407 1.1 mrg
3408 1.1 mrg if (v == 1)
3409 1.1 mrg {
3410 1.1 mrg /* 1**something is always 1. */
3411 1.1 mrg se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3412 1.1 mrg return;
3413 1.1 mrg }
3414 1.1 mrg else if (v == -1)
3415 1.1 mrg {
3416 1.1 mrg /* (-1)**n is 1 - ((n & 1) << 1) */
3417 1.1 mrg tree type;
3418 1.1 mrg tree tmp;
3419 1.1 mrg
3420 1.1 mrg type = TREE_TYPE (lse.expr);
3421 1.1 mrg tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3422 1.1 mrg rse.expr, build_int_cst (type, 1));
3423 1.1 mrg tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3424 1.1 mrg tmp, build_int_cst (type, 1));
3425 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3426 1.1 mrg build_int_cst (type, 1), tmp);
3427 1.1 mrg se->expr = tmp;
3428 1.1 mrg return;
3429 1.1 mrg }
3430 1.1 mrg else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3431 1.1 mrg {
3432 1.1 mrg /* Here v is +/- 2**e. The further simplification uses
3433 1.1 mrg 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3434 1.1 mrg 1<<(4*n), etc., but we have to make sure to return zero
3435 1.1 mrg if the number of bits is too large. */
3436 1.1 mrg tree lshift;
3437 1.1 mrg tree type;
3438 1.1 mrg tree shift;
3439 1.1 mrg tree ge;
3440 1.1 mrg tree cond;
3441 1.1 mrg tree num_bits;
3442 1.1 mrg tree cond2;
3443 1.1 mrg tree tmp1;
3444 1.1 mrg
3445 1.1 mrg type = TREE_TYPE (lse.expr);
3446 1.1 mrg
3447 1.1 mrg if (w == 2)
3448 1.1 mrg shift = rse.expr;
3449 1.1 mrg else if (w == 4)
3450 1.1 mrg shift = fold_build2_loc (input_location, PLUS_EXPR,
3451 1.1 mrg TREE_TYPE (rse.expr),
3452 1.1 mrg rse.expr, rse.expr);
3453 1.1 mrg else
3454 1.1 mrg {
3455 1.1 mrg /* use popcount for fast log2(w) */
3456 1.1 mrg int e = wi::popcount (w-1);
3457 1.1 mrg shift = fold_build2_loc (input_location, MULT_EXPR,
3458 1.1 mrg TREE_TYPE (rse.expr),
3459 1.1 mrg build_int_cst (TREE_TYPE (rse.expr), e),
3460 1.1 mrg rse.expr);
3461 1.1 mrg }
3462 1.1 mrg
3463 1.1 mrg lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3464 1.1 mrg build_int_cst (type, 1), shift);
3465 1.1 mrg ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3466 1.1 mrg rse.expr, build_int_cst (type, 0));
3467 1.1 mrg cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3468 1.1 mrg build_int_cst (type, 0));
3469 1.1 mrg num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3470 1.1 mrg cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3471 1.1 mrg rse.expr, num_bits);
3472 1.1 mrg tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3473 1.1 mrg build_int_cst (type, 0), cond);
3474 1.1 mrg if (v > 0)
3475 1.1 mrg {
3476 1.1 mrg se->expr = tmp1;
3477 1.1 mrg }
3478 1.1 mrg else
3479 1.1 mrg {
3480 1.1 mrg /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3481 1.1 mrg tree tmp2;
3482 1.1 mrg tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3483 1.1 mrg rse.expr, build_int_cst (type, 1));
3484 1.1 mrg tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3485 1.1 mrg tmp2, build_int_cst (type, 1));
3486 1.1 mrg tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3487 1.1 mrg build_int_cst (type, 1), tmp2);
3488 1.1 mrg se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3489 1.1 mrg tmp1, tmp2);
3490 1.1 mrg }
3491 1.1 mrg return;
3492 1.1 mrg }
3493 1.1 mrg }
3494 1.1 mrg
3495 1.1 mrg gfc_int4_type_node = gfc_get_int_type (4);
3496 1.1 mrg
3497 1.1 mrg /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3498 1.1 mrg library routine. But in the end, we have to convert the result back
3499 1.1 mrg if this case applies -- with res_ikind_K, we keep track whether operand K
3500 1.1 mrg falls into this case. */
3501 1.1 mrg res_ikind_1 = -1;
3502 1.1 mrg res_ikind_2 = -1;
3503 1.1 mrg
3504 1.1 mrg kind = expr->value.op.op1->ts.kind;
3505 1.1 mrg switch (expr->value.op.op2->ts.type)
3506 1.1 mrg {
3507 1.1 mrg case BT_INTEGER:
3508 1.1 mrg ikind = expr->value.op.op2->ts.kind;
3509 1.1 mrg switch (ikind)
3510 1.1 mrg {
3511 1.1 mrg case 1:
3512 1.1 mrg case 2:
3513 1.1 mrg rse.expr = convert (gfc_int4_type_node, rse.expr);
3514 1.1 mrg res_ikind_2 = ikind;
3515 1.1 mrg /* Fall through. */
3516 1.1 mrg
3517 1.1 mrg case 4:
3518 1.1 mrg ikind = 0;
3519 1.1 mrg break;
3520 1.1 mrg
3521 1.1 mrg case 8:
3522 1.1 mrg ikind = 1;
3523 1.1 mrg break;
3524 1.1 mrg
3525 1.1 mrg case 16:
3526 1.1 mrg ikind = 2;
3527 1.1 mrg break;
3528 1.1 mrg
3529 1.1 mrg default:
3530 1.1 mrg gcc_unreachable ();
3531 1.1 mrg }
3532 1.1 mrg switch (kind)
3533 1.1 mrg {
3534 1.1 mrg case 1:
3535 1.1 mrg case 2:
3536 1.1 mrg if (expr->value.op.op1->ts.type == BT_INTEGER)
3537 1.1 mrg {
3538 1.1 mrg lse.expr = convert (gfc_int4_type_node, lse.expr);
3539 1.1 mrg res_ikind_1 = kind;
3540 1.1 mrg }
3541 1.1 mrg else
3542 1.1 mrg gcc_unreachable ();
3543 1.1 mrg /* Fall through. */
3544 1.1 mrg
3545 1.1 mrg case 4:
3546 1.1 mrg kind = 0;
3547 1.1 mrg break;
3548 1.1 mrg
3549 1.1 mrg case 8:
3550 1.1 mrg kind = 1;
3551 1.1 mrg break;
3552 1.1 mrg
3553 1.1 mrg case 10:
3554 1.1 mrg kind = 2;
3555 1.1 mrg break;
3556 1.1 mrg
3557 1.1 mrg case 16:
3558 1.1 mrg kind = 3;
3559 1.1 mrg break;
3560 1.1 mrg
3561 1.1 mrg default:
3562 1.1 mrg gcc_unreachable ();
3563 1.1 mrg }
3564 1.1 mrg
3565 1.1 mrg switch (expr->value.op.op1->ts.type)
3566 1.1 mrg {
3567 1.1 mrg case BT_INTEGER:
3568 1.1 mrg if (kind == 3) /* Case 16 was not handled properly above. */
3569 1.1 mrg kind = 2;
3570 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3571 1.1 mrg break;
3572 1.1 mrg
3573 1.1 mrg case BT_REAL:
3574 1.1 mrg /* Use builtins for real ** int4. */
3575 1.1 mrg if (ikind == 0)
3576 1.1 mrg {
3577 1.1 mrg switch (kind)
3578 1.1 mrg {
3579 1.1 mrg case 0:
3580 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3581 1.1 mrg break;
3582 1.1 mrg
3583 1.1 mrg case 1:
3584 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3585 1.1 mrg break;
3586 1.1 mrg
3587 1.1 mrg case 2:
3588 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3589 1.1 mrg break;
3590 1.1 mrg
3591 1.1 mrg case 3:
3592 1.1 mrg /* Use the __builtin_powil() only if real(kind=16) is
3593 1.1 mrg actually the C long double type. */
3594 1.1 mrg if (!gfc_real16_is_float128)
3595 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3596 1.1 mrg break;
3597 1.1 mrg
3598 1.1 mrg default:
3599 1.1 mrg gcc_unreachable ();
3600 1.1 mrg }
3601 1.1 mrg }
3602 1.1 mrg
3603 1.1 mrg /* If we don't have a good builtin for this, go for the
3604 1.1 mrg library function. */
3605 1.1 mrg if (!fndecl)
3606 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3607 1.1 mrg break;
3608 1.1 mrg
3609 1.1 mrg case BT_COMPLEX:
3610 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3611 1.1 mrg break;
3612 1.1 mrg
3613 1.1 mrg default:
3614 1.1 mrg gcc_unreachable ();
3615 1.1 mrg }
3616 1.1 mrg break;
3617 1.1 mrg
3618 1.1 mrg case BT_REAL:
3619 1.1 mrg fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3620 1.1 mrg break;
3621 1.1 mrg
3622 1.1 mrg case BT_COMPLEX:
3623 1.1 mrg fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3624 1.1 mrg break;
3625 1.1 mrg
3626 1.1 mrg default:
3627 1.1 mrg gcc_unreachable ();
3628 1.1 mrg break;
3629 1.1 mrg }
3630 1.1 mrg
3631 1.1 mrg se->expr = build_call_expr_loc (input_location,
3632 1.1 mrg fndecl, 2, lse.expr, rse.expr);
3633 1.1 mrg
3634 1.1 mrg /* Convert the result back if it is of wrong integer kind. */
3635 1.1 mrg if (res_ikind_1 != -1 && res_ikind_2 != -1)
3636 1.1 mrg {
3637 1.1 mrg /* We want the maximum of both operand kinds as result. */
3638 1.1 mrg if (res_ikind_1 < res_ikind_2)
3639 1.1 mrg res_ikind_1 = res_ikind_2;
3640 1.1 mrg se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3641 1.1 mrg }
3642 1.1 mrg }
3643 1.1 mrg
3644 1.1 mrg
3645 1.1 mrg /* Generate code to allocate a string temporary. */
3646 1.1 mrg
3647 1.1 mrg tree
3648 1.1 mrg gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3649 1.1 mrg {
3650 1.1 mrg tree var;
3651 1.1 mrg tree tmp;
3652 1.1 mrg
3653 1.1 mrg if (gfc_can_put_var_on_stack (len))
3654 1.1 mrg {
3655 1.1 mrg /* Create a temporary variable to hold the result. */
3656 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
3657 1.1 mrg TREE_TYPE (len), len,
3658 1.1 mrg build_int_cst (TREE_TYPE (len), 1));
3659 1.1 mrg tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3660 1.1 mrg
3661 1.1 mrg if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3662 1.1 mrg tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3663 1.1 mrg else
3664 1.1 mrg tmp = build_array_type (TREE_TYPE (type), tmp);
3665 1.1 mrg
3666 1.1 mrg var = gfc_create_var (tmp, "str");
3667 1.1 mrg var = gfc_build_addr_expr (type, var);
3668 1.1 mrg }
3669 1.1 mrg else
3670 1.1 mrg {
3671 1.1 mrg /* Allocate a temporary to hold the result. */
3672 1.1 mrg var = gfc_create_var (type, "pstr");
3673 1.1 mrg gcc_assert (POINTER_TYPE_P (type));
3674 1.1 mrg tmp = TREE_TYPE (type);
3675 1.1 mrg if (TREE_CODE (tmp) == ARRAY_TYPE)
3676 1.1 mrg tmp = TREE_TYPE (tmp);
3677 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp);
3678 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3679 1.1 mrg fold_convert (size_type_node, len),
3680 1.1 mrg fold_convert (size_type_node, tmp));
3681 1.1 mrg tmp = gfc_call_malloc (&se->pre, type, tmp);
3682 1.1 mrg gfc_add_modify (&se->pre, var, tmp);
3683 1.1 mrg
3684 1.1 mrg /* Free the temporary afterwards. */
3685 1.1 mrg tmp = gfc_call_free (var);
3686 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
3687 1.1 mrg }
3688 1.1 mrg
3689 1.1 mrg return var;
3690 1.1 mrg }
3691 1.1 mrg
3692 1.1 mrg
3693 1.1 mrg /* Handle a string concatenation operation. A temporary will be allocated to
3694 1.1 mrg hold the result. */
3695 1.1 mrg
3696 1.1 mrg static void
3697 1.1 mrg gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3698 1.1 mrg {
3699 1.1 mrg gfc_se lse, rse;
3700 1.1 mrg tree len, type, var, tmp, fndecl;
3701 1.1 mrg
3702 1.1 mrg gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3703 1.1 mrg && expr->value.op.op2->ts.type == BT_CHARACTER);
3704 1.1 mrg gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3705 1.1 mrg
3706 1.1 mrg gfc_init_se (&lse, se);
3707 1.1 mrg gfc_conv_expr (&lse, expr->value.op.op1);
3708 1.1 mrg gfc_conv_string_parameter (&lse);
3709 1.1 mrg gfc_init_se (&rse, se);
3710 1.1 mrg gfc_conv_expr (&rse, expr->value.op.op2);
3711 1.1 mrg gfc_conv_string_parameter (&rse);
3712 1.1 mrg
3713 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre);
3714 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre);
3715 1.1 mrg
3716 1.1 mrg type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3717 1.1 mrg len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3718 1.1 mrg if (len == NULL_TREE)
3719 1.1 mrg {
3720 1.1 mrg len = fold_build2_loc (input_location, PLUS_EXPR,
3721 1.1 mrg gfc_charlen_type_node,
3722 1.1 mrg fold_convert (gfc_charlen_type_node,
3723 1.1 mrg lse.string_length),
3724 1.1 mrg fold_convert (gfc_charlen_type_node,
3725 1.1 mrg rse.string_length));
3726 1.1 mrg }
3727 1.1 mrg
3728 1.1 mrg type = build_pointer_type (type);
3729 1.1 mrg
3730 1.1 mrg var = gfc_conv_string_tmp (se, type, len);
3731 1.1 mrg
3732 1.1 mrg /* Do the actual concatenation. */
3733 1.1 mrg if (expr->ts.kind == 1)
3734 1.1 mrg fndecl = gfor_fndecl_concat_string;
3735 1.1 mrg else if (expr->ts.kind == 4)
3736 1.1 mrg fndecl = gfor_fndecl_concat_string_char4;
3737 1.1 mrg else
3738 1.1 mrg gcc_unreachable ();
3739 1.1 mrg
3740 1.1 mrg tmp = build_call_expr_loc (input_location,
3741 1.1 mrg fndecl, 6, len, var, lse.string_length, lse.expr,
3742 1.1 mrg rse.string_length, rse.expr);
3743 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
3744 1.1 mrg
3745 1.1 mrg /* Add the cleanup for the operands. */
3746 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.post);
3747 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post);
3748 1.1 mrg
3749 1.1 mrg se->expr = var;
3750 1.1 mrg se->string_length = len;
3751 1.1 mrg }
3752 1.1 mrg
3753 1.1 mrg /* Translates an op expression. Common (binary) cases are handled by this
3754 1.1 mrg function, others are passed on. Recursion is used in either case.
3755 1.1 mrg We use the fact that (op1.ts == op2.ts) (except for the power
3756 1.1 mrg operator **).
3757 1.1 mrg Operators need no special handling for scalarized expressions as long as
3758 1.1 mrg they call gfc_conv_simple_val to get their operands.
3759 1.1 mrg Character strings get special handling. */
3760 1.1 mrg
3761 1.1 mrg static void
3762 1.1 mrg gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3763 1.1 mrg {
3764 1.1 mrg enum tree_code code;
3765 1.1 mrg gfc_se lse;
3766 1.1 mrg gfc_se rse;
3767 1.1 mrg tree tmp, type;
3768 1.1 mrg int lop;
3769 1.1 mrg int checkstring;
3770 1.1 mrg
3771 1.1 mrg checkstring = 0;
3772 1.1 mrg lop = 0;
3773 1.1 mrg switch (expr->value.op.op)
3774 1.1 mrg {
3775 1.1 mrg case INTRINSIC_PARENTHESES:
3776 1.1 mrg if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3777 1.1 mrg && flag_protect_parens)
3778 1.1 mrg {
3779 1.1 mrg gfc_conv_unary_op (PAREN_EXPR, se, expr);
3780 1.1 mrg gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3781 1.1 mrg return;
3782 1.1 mrg }
3783 1.1 mrg
3784 1.1 mrg /* Fallthrough. */
3785 1.1 mrg case INTRINSIC_UPLUS:
3786 1.1 mrg gfc_conv_expr (se, expr->value.op.op1);
3787 1.1 mrg return;
3788 1.1 mrg
3789 1.1 mrg case INTRINSIC_UMINUS:
3790 1.1 mrg gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3791 1.1 mrg return;
3792 1.1 mrg
3793 1.1 mrg case INTRINSIC_NOT:
3794 1.1 mrg gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3795 1.1 mrg return;
3796 1.1 mrg
3797 1.1 mrg case INTRINSIC_PLUS:
3798 1.1 mrg code = PLUS_EXPR;
3799 1.1 mrg break;
3800 1.1 mrg
3801 1.1 mrg case INTRINSIC_MINUS:
3802 1.1 mrg code = MINUS_EXPR;
3803 1.1 mrg break;
3804 1.1 mrg
3805 1.1 mrg case INTRINSIC_TIMES:
3806 1.1 mrg code = MULT_EXPR;
3807 1.1 mrg break;
3808 1.1 mrg
3809 1.1 mrg case INTRINSIC_DIVIDE:
3810 1.1 mrg /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3811 1.1 mrg an integer, we must round towards zero, so we use a
3812 1.1 mrg TRUNC_DIV_EXPR. */
3813 1.1 mrg if (expr->ts.type == BT_INTEGER)
3814 1.1 mrg code = TRUNC_DIV_EXPR;
3815 1.1 mrg else
3816 1.1 mrg code = RDIV_EXPR;
3817 1.1 mrg break;
3818 1.1 mrg
3819 1.1 mrg case INTRINSIC_POWER:
3820 1.1 mrg gfc_conv_power_op (se, expr);
3821 1.1 mrg return;
3822 1.1 mrg
3823 1.1 mrg case INTRINSIC_CONCAT:
3824 1.1 mrg gfc_conv_concat_op (se, expr);
3825 1.1 mrg return;
3826 1.1 mrg
3827 1.1 mrg case INTRINSIC_AND:
3828 1.1 mrg code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3829 1.1 mrg lop = 1;
3830 1.1 mrg break;
3831 1.1 mrg
3832 1.1 mrg case INTRINSIC_OR:
3833 1.1 mrg code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3834 1.1 mrg lop = 1;
3835 1.1 mrg break;
3836 1.1 mrg
3837 1.1 mrg /* EQV and NEQV only work on logicals, but since we represent them
3838 1.1 mrg as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3839 1.1 mrg case INTRINSIC_EQ:
3840 1.1 mrg case INTRINSIC_EQ_OS:
3841 1.1 mrg case INTRINSIC_EQV:
3842 1.1 mrg code = EQ_EXPR;
3843 1.1 mrg checkstring = 1;
3844 1.1 mrg lop = 1;
3845 1.1 mrg break;
3846 1.1 mrg
3847 1.1 mrg case INTRINSIC_NE:
3848 1.1 mrg case INTRINSIC_NE_OS:
3849 1.1 mrg case INTRINSIC_NEQV:
3850 1.1 mrg code = NE_EXPR;
3851 1.1 mrg checkstring = 1;
3852 1.1 mrg lop = 1;
3853 1.1 mrg break;
3854 1.1 mrg
3855 1.1 mrg case INTRINSIC_GT:
3856 1.1 mrg case INTRINSIC_GT_OS:
3857 1.1 mrg code = GT_EXPR;
3858 1.1 mrg checkstring = 1;
3859 1.1 mrg lop = 1;
3860 1.1 mrg break;
3861 1.1 mrg
3862 1.1 mrg case INTRINSIC_GE:
3863 1.1 mrg case INTRINSIC_GE_OS:
3864 1.1 mrg code = GE_EXPR;
3865 1.1 mrg checkstring = 1;
3866 1.1 mrg lop = 1;
3867 1.1 mrg break;
3868 1.1 mrg
3869 1.1 mrg case INTRINSIC_LT:
3870 1.1 mrg case INTRINSIC_LT_OS:
3871 1.1 mrg code = LT_EXPR;
3872 1.1 mrg checkstring = 1;
3873 1.1 mrg lop = 1;
3874 1.1 mrg break;
3875 1.1 mrg
3876 1.1 mrg case INTRINSIC_LE:
3877 1.1 mrg case INTRINSIC_LE_OS:
3878 1.1 mrg code = LE_EXPR;
3879 1.1 mrg checkstring = 1;
3880 1.1 mrg lop = 1;
3881 1.1 mrg break;
3882 1.1 mrg
3883 1.1 mrg case INTRINSIC_USER:
3884 1.1 mrg case INTRINSIC_ASSIGN:
3885 1.1 mrg /* These should be converted into function calls by the frontend. */
3886 1.1 mrg gcc_unreachable ();
3887 1.1 mrg
3888 1.1 mrg default:
3889 1.1 mrg fatal_error (input_location, "Unknown intrinsic op");
3890 1.1 mrg return;
3891 1.1 mrg }
3892 1.1 mrg
3893 1.1 mrg /* The only exception to this is **, which is handled separately anyway. */
3894 1.1 mrg gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3895 1.1 mrg
3896 1.1 mrg if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3897 1.1 mrg checkstring = 0;
3898 1.1 mrg
3899 1.1 mrg /* lhs */
3900 1.1 mrg gfc_init_se (&lse, se);
3901 1.1 mrg gfc_conv_expr (&lse, expr->value.op.op1);
3902 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre);
3903 1.1 mrg
3904 1.1 mrg /* rhs */
3905 1.1 mrg gfc_init_se (&rse, se);
3906 1.1 mrg gfc_conv_expr (&rse, expr->value.op.op2);
3907 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre);
3908 1.1 mrg
3909 1.1 mrg if (checkstring)
3910 1.1 mrg {
3911 1.1 mrg gfc_conv_string_parameter (&lse);
3912 1.1 mrg gfc_conv_string_parameter (&rse);
3913 1.1 mrg
3914 1.1 mrg lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3915 1.1 mrg rse.string_length, rse.expr,
3916 1.1 mrg expr->value.op.op1->ts.kind,
3917 1.1 mrg code);
3918 1.1 mrg rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3919 1.1 mrg gfc_add_block_to_block (&lse.post, &rse.post);
3920 1.1 mrg }
3921 1.1 mrg
3922 1.1 mrg type = gfc_typenode_for_spec (&expr->ts);
3923 1.1 mrg
3924 1.1 mrg if (lop)
3925 1.1 mrg {
3926 1.1 mrg // Inhibit overeager optimization of Cray pointer comparisons (PR106692).
3927 1.1 mrg if (expr->value.op.op1->expr_type == EXPR_VARIABLE
3928 1.1 mrg && expr->value.op.op1->ts.type == BT_INTEGER
3929 1.1 mrg && expr->value.op.op1->symtree
3930 1.1 mrg && expr->value.op.op1->symtree->n.sym->attr.cray_pointer)
3931 1.1 mrg TREE_THIS_VOLATILE (lse.expr) = 1;
3932 1.1 mrg
3933 1.1 mrg if (expr->value.op.op2->expr_type == EXPR_VARIABLE
3934 1.1 mrg && expr->value.op.op2->ts.type == BT_INTEGER
3935 1.1 mrg && expr->value.op.op2->symtree
3936 1.1 mrg && expr->value.op.op2->symtree->n.sym->attr.cray_pointer)
3937 1.1 mrg TREE_THIS_VOLATILE (rse.expr) = 1;
3938 1.1 mrg
3939 1.1 mrg /* The result of logical ops is always logical_type_node. */
3940 1.1 mrg tmp = fold_build2_loc (input_location, code, logical_type_node,
3941 1.1 mrg lse.expr, rse.expr);
3942 1.1 mrg se->expr = convert (type, tmp);
3943 1.1 mrg }
3944 1.1 mrg else
3945 1.1 mrg se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3946 1.1 mrg
3947 1.1 mrg /* Add the post blocks. */
3948 1.1 mrg gfc_add_block_to_block (&se->post, &rse.post);
3949 1.1 mrg gfc_add_block_to_block (&se->post, &lse.post);
3950 1.1 mrg }
3951 1.1 mrg
3952 1.1 mrg /* If a string's length is one, we convert it to a single character. */
3953 1.1 mrg
3954 1.1 mrg tree
3955 1.1 mrg gfc_string_to_single_character (tree len, tree str, int kind)
3956 1.1 mrg {
3957 1.1 mrg
3958 1.1 mrg if (len == NULL
3959 1.1 mrg || !tree_fits_uhwi_p (len)
3960 1.1 mrg || !POINTER_TYPE_P (TREE_TYPE (str)))
3961 1.1 mrg return NULL_TREE;
3962 1.1 mrg
3963 1.1 mrg if (TREE_INT_CST_LOW (len) == 1)
3964 1.1 mrg {
3965 1.1 mrg str = fold_convert (gfc_get_pchar_type (kind), str);
3966 1.1 mrg return build_fold_indirect_ref_loc (input_location, str);
3967 1.1 mrg }
3968 1.1 mrg
3969 1.1 mrg if (kind == 1
3970 1.1 mrg && TREE_CODE (str) == ADDR_EXPR
3971 1.1 mrg && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3972 1.1 mrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3973 1.1 mrg && array_ref_low_bound (TREE_OPERAND (str, 0))
3974 1.1 mrg == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3975 1.1 mrg && TREE_INT_CST_LOW (len) > 1
3976 1.1 mrg && TREE_INT_CST_LOW (len)
3977 1.1 mrg == (unsigned HOST_WIDE_INT)
3978 1.1 mrg TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3979 1.1 mrg {
3980 1.1 mrg tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3981 1.1 mrg ret = build_fold_indirect_ref_loc (input_location, ret);
3982 1.1 mrg if (TREE_CODE (ret) == INTEGER_CST)
3983 1.1 mrg {
3984 1.1 mrg tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3985 1.1 mrg int i, length = TREE_STRING_LENGTH (string_cst);
3986 1.1 mrg const char *ptr = TREE_STRING_POINTER (string_cst);
3987 1.1 mrg
3988 1.1 mrg for (i = 1; i < length; i++)
3989 1.1 mrg if (ptr[i] != ' ')
3990 1.1 mrg return NULL_TREE;
3991 1.1 mrg
3992 1.1 mrg return ret;
3993 1.1 mrg }
3994 1.1 mrg }
3995 1.1 mrg
3996 1.1 mrg return NULL_TREE;
3997 1.1 mrg }
3998 1.1 mrg
3999 1.1 mrg
4000 1.1 mrg static void
4001 1.1 mrg conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
4002 1.1 mrg {
4003 1.1 mrg gcc_assert (expr);
4004 1.1 mrg
4005 1.1 mrg /* We used to modify the tree here. Now it is done earlier in
4006 1.1 mrg the front-end, so we only check it here to avoid regressions. */
4007 1.1 mrg if (sym->backend_decl)
4008 1.1 mrg {
4009 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
4010 1.1 mrg gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
4011 1.1 mrg gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
4012 1.1 mrg gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
4013 1.1 mrg }
4014 1.1 mrg
4015 1.1 mrg /* If we have a constant character expression, make it into an
4016 1.1 mrg integer of type C char. */
4017 1.1 mrg if ((*expr)->expr_type == EXPR_CONSTANT)
4018 1.1 mrg {
4019 1.1 mrg gfc_typespec ts;
4020 1.1 mrg gfc_clear_ts (&ts);
4021 1.1 mrg
4022 1.1 mrg *expr = gfc_get_int_expr (gfc_default_character_kind, NULL,
4023 1.1 mrg (*expr)->value.character.string[0]);
4024 1.1 mrg }
4025 1.1 mrg else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4026 1.1 mrg {
4027 1.1 mrg if ((*expr)->ref == NULL)
4028 1.1 mrg {
4029 1.1 mrg se->expr = gfc_string_to_single_character
4030 1.1 mrg (build_int_cst (integer_type_node, 1),
4031 1.1 mrg gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4032 1.1 mrg gfc_get_symbol_decl
4033 1.1 mrg ((*expr)->symtree->n.sym)),
4034 1.1 mrg (*expr)->ts.kind);
4035 1.1 mrg }
4036 1.1 mrg else
4037 1.1 mrg {
4038 1.1 mrg gfc_conv_variable (se, *expr);
4039 1.1 mrg se->expr = gfc_string_to_single_character
4040 1.1 mrg (build_int_cst (integer_type_node, 1),
4041 1.1 mrg gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4042 1.1 mrg se->expr),
4043 1.1 mrg (*expr)->ts.kind);
4044 1.1 mrg }
4045 1.1 mrg }
4046 1.1 mrg }
4047 1.1 mrg
4048 1.1 mrg /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4049 1.1 mrg if STR is a string literal, otherwise return -1. */
4050 1.1 mrg
4051 1.1 mrg static int
4052 1.1 mrg gfc_optimize_len_trim (tree len, tree str, int kind)
4053 1.1 mrg {
4054 1.1 mrg if (kind == 1
4055 1.1 mrg && TREE_CODE (str) == ADDR_EXPR
4056 1.1 mrg && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4057 1.1 mrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4058 1.1 mrg && array_ref_low_bound (TREE_OPERAND (str, 0))
4059 1.1 mrg == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4060 1.1 mrg && tree_fits_uhwi_p (len)
4061 1.1 mrg && tree_to_uhwi (len) >= 1
4062 1.1 mrg && tree_to_uhwi (len)
4063 1.1 mrg == (unsigned HOST_WIDE_INT)
4064 1.1 mrg TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4065 1.1 mrg {
4066 1.1 mrg tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4067 1.1 mrg folded = build_fold_indirect_ref_loc (input_location, folded);
4068 1.1 mrg if (TREE_CODE (folded) == INTEGER_CST)
4069 1.1 mrg {
4070 1.1 mrg tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4071 1.1 mrg int length = TREE_STRING_LENGTH (string_cst);
4072 1.1 mrg const char *ptr = TREE_STRING_POINTER (string_cst);
4073 1.1 mrg
4074 1.1 mrg for (; length > 0; length--)
4075 1.1 mrg if (ptr[length - 1] != ' ')
4076 1.1 mrg break;
4077 1.1 mrg
4078 1.1 mrg return length;
4079 1.1 mrg }
4080 1.1 mrg }
4081 1.1 mrg return -1;
4082 1.1 mrg }
4083 1.1 mrg
4084 1.1 mrg /* Helper to build a call to memcmp. */
4085 1.1 mrg
4086 1.1 mrg static tree
4087 1.1 mrg build_memcmp_call (tree s1, tree s2, tree n)
4088 1.1 mrg {
4089 1.1 mrg tree tmp;
4090 1.1 mrg
4091 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4092 1.1 mrg s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4093 1.1 mrg else
4094 1.1 mrg s1 = fold_convert (pvoid_type_node, s1);
4095 1.1 mrg
4096 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4097 1.1 mrg s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4098 1.1 mrg else
4099 1.1 mrg s2 = fold_convert (pvoid_type_node, s2);
4100 1.1 mrg
4101 1.1 mrg n = fold_convert (size_type_node, n);
4102 1.1 mrg
4103 1.1 mrg tmp = build_call_expr_loc (input_location,
4104 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMCMP),
4105 1.1 mrg 3, s1, s2, n);
4106 1.1 mrg
4107 1.1 mrg return fold_convert (integer_type_node, tmp);
4108 1.1 mrg }
4109 1.1 mrg
4110 1.1 mrg /* Compare two strings. If they are all single characters, the result is the
4111 1.1 mrg subtraction of them. Otherwise, we build a library call. */
4112 1.1 mrg
4113 1.1 mrg tree
4114 1.1 mrg gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4115 1.1 mrg enum tree_code code)
4116 1.1 mrg {
4117 1.1 mrg tree sc1;
4118 1.1 mrg tree sc2;
4119 1.1 mrg tree fndecl;
4120 1.1 mrg
4121 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4122 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4123 1.1 mrg
4124 1.1 mrg sc1 = gfc_string_to_single_character (len1, str1, kind);
4125 1.1 mrg sc2 = gfc_string_to_single_character (len2, str2, kind);
4126 1.1 mrg
4127 1.1 mrg if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4128 1.1 mrg {
4129 1.1 mrg /* Deal with single character specially. */
4130 1.1 mrg sc1 = fold_convert (integer_type_node, sc1);
4131 1.1 mrg sc2 = fold_convert (integer_type_node, sc2);
4132 1.1 mrg return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4133 1.1 mrg sc1, sc2);
4134 1.1 mrg }
4135 1.1 mrg
4136 1.1 mrg if ((code == EQ_EXPR || code == NE_EXPR)
4137 1.1 mrg && optimize
4138 1.1 mrg && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4139 1.1 mrg {
4140 1.1 mrg /* If one string is a string literal with LEN_TRIM longer
4141 1.1 mrg than the length of the second string, the strings
4142 1.1 mrg compare unequal. */
4143 1.1 mrg int len = gfc_optimize_len_trim (len1, str1, kind);
4144 1.1 mrg if (len > 0 && compare_tree_int (len2, len) < 0)
4145 1.1 mrg return integer_one_node;
4146 1.1 mrg len = gfc_optimize_len_trim (len2, str2, kind);
4147 1.1 mrg if (len > 0 && compare_tree_int (len1, len) < 0)
4148 1.1 mrg return integer_one_node;
4149 1.1 mrg }
4150 1.1 mrg
4151 1.1 mrg /* We can compare via memcpy if the strings are known to be equal
4152 1.1 mrg in length and they are
4153 1.1 mrg - kind=1
4154 1.1 mrg - kind=4 and the comparison is for (in)equality. */
4155 1.1 mrg
4156 1.1 mrg if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4157 1.1 mrg && tree_int_cst_equal (len1, len2)
4158 1.1 mrg && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4159 1.1 mrg {
4160 1.1 mrg tree tmp;
4161 1.1 mrg tree chartype;
4162 1.1 mrg
4163 1.1 mrg chartype = gfc_get_char_type (kind);
4164 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4165 1.1 mrg fold_convert (TREE_TYPE(len1),
4166 1.1 mrg TYPE_SIZE_UNIT(chartype)),
4167 1.1 mrg len1);
4168 1.1 mrg return build_memcmp_call (str1, str2, tmp);
4169 1.1 mrg }
4170 1.1 mrg
4171 1.1 mrg /* Build a call for the comparison. */
4172 1.1 mrg if (kind == 1)
4173 1.1 mrg fndecl = gfor_fndecl_compare_string;
4174 1.1 mrg else if (kind == 4)
4175 1.1 mrg fndecl = gfor_fndecl_compare_string_char4;
4176 1.1 mrg else
4177 1.1 mrg gcc_unreachable ();
4178 1.1 mrg
4179 1.1 mrg return build_call_expr_loc (input_location, fndecl, 4,
4180 1.1 mrg len1, str1, len2, str2);
4181 1.1 mrg }
4182 1.1 mrg
4183 1.1 mrg
4184 1.1 mrg /* Return the backend_decl for a procedure pointer component. */
4185 1.1 mrg
4186 1.1 mrg static tree
4187 1.1 mrg get_proc_ptr_comp (gfc_expr *e)
4188 1.1 mrg {
4189 1.1 mrg gfc_se comp_se;
4190 1.1 mrg gfc_expr *e2;
4191 1.1 mrg expr_t old_type;
4192 1.1 mrg
4193 1.1 mrg gfc_init_se (&comp_se, NULL);
4194 1.1 mrg e2 = gfc_copy_expr (e);
4195 1.1 mrg /* We have to restore the expr type later so that gfc_free_expr frees
4196 1.1 mrg the exact same thing that was allocated.
4197 1.1 mrg TODO: This is ugly. */
4198 1.1 mrg old_type = e2->expr_type;
4199 1.1 mrg e2->expr_type = EXPR_VARIABLE;
4200 1.1 mrg gfc_conv_expr (&comp_se, e2);
4201 1.1 mrg e2->expr_type = old_type;
4202 1.1 mrg gfc_free_expr (e2);
4203 1.1 mrg return build_fold_addr_expr_loc (input_location, comp_se.expr);
4204 1.1 mrg }
4205 1.1 mrg
4206 1.1 mrg
4207 1.1 mrg /* Convert a typebound function reference from a class object. */
4208 1.1 mrg static void
4209 1.1 mrg conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4210 1.1 mrg {
4211 1.1 mrg gfc_ref *ref;
4212 1.1 mrg tree var;
4213 1.1 mrg
4214 1.1 mrg if (!VAR_P (base_object))
4215 1.1 mrg {
4216 1.1 mrg var = gfc_create_var (TREE_TYPE (base_object), NULL);
4217 1.1 mrg gfc_add_modify (&se->pre, var, base_object);
4218 1.1 mrg }
4219 1.1 mrg se->expr = gfc_class_vptr_get (base_object);
4220 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4221 1.1 mrg ref = expr->ref;
4222 1.1 mrg while (ref && ref->next)
4223 1.1 mrg ref = ref->next;
4224 1.1 mrg gcc_assert (ref && ref->type == REF_COMPONENT);
4225 1.1 mrg if (ref->u.c.sym->attr.extension)
4226 1.1 mrg conv_parent_component_references (se, ref);
4227 1.1 mrg gfc_conv_component_ref (se, ref);
4228 1.1 mrg se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4229 1.1 mrg }
4230 1.1 mrg
4231 1.1 mrg
4232 1.1 mrg static void
4233 1.1 mrg conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4234 1.1 mrg gfc_actual_arglist *actual_args)
4235 1.1 mrg {
4236 1.1 mrg tree tmp;
4237 1.1 mrg
4238 1.1 mrg if (gfc_is_proc_ptr_comp (expr))
4239 1.1 mrg tmp = get_proc_ptr_comp (expr);
4240 1.1 mrg else if (sym->attr.dummy)
4241 1.1 mrg {
4242 1.1 mrg tmp = gfc_get_symbol_decl (sym);
4243 1.1 mrg if (sym->attr.proc_pointer)
4244 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
4245 1.1 mrg tmp);
4246 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4247 1.1 mrg && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4248 1.1 mrg }
4249 1.1 mrg else
4250 1.1 mrg {
4251 1.1 mrg if (!sym->backend_decl)
4252 1.1 mrg sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
4253 1.1 mrg
4254 1.1 mrg TREE_USED (sym->backend_decl) = 1;
4255 1.1 mrg
4256 1.1 mrg tmp = sym->backend_decl;
4257 1.1 mrg
4258 1.1 mrg if (sym->attr.cray_pointee)
4259 1.1 mrg {
4260 1.1 mrg /* TODO - make the cray pointee a pointer to a procedure,
4261 1.1 mrg assign the pointer to it and use it for the call. This
4262 1.1 mrg will do for now! */
4263 1.1 mrg tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4264 1.1 mrg gfc_get_symbol_decl (sym->cp_pointer));
4265 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre);
4266 1.1 mrg }
4267 1.1 mrg
4268 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4269 1.1 mrg {
4270 1.1 mrg gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
4271 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4272 1.1 mrg }
4273 1.1 mrg }
4274 1.1 mrg se->expr = tmp;
4275 1.1 mrg }
4276 1.1 mrg
4277 1.1 mrg
4278 1.1 mrg /* Initialize MAPPING. */
4279 1.1 mrg
4280 1.1 mrg void
4281 1.1 mrg gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4282 1.1 mrg {
4283 1.1 mrg mapping->syms = NULL;
4284 1.1 mrg mapping->charlens = NULL;
4285 1.1 mrg }
4286 1.1 mrg
4287 1.1 mrg
4288 1.1 mrg /* Free all memory held by MAPPING (but not MAPPING itself). */
4289 1.1 mrg
4290 1.1 mrg void
4291 1.1 mrg gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4292 1.1 mrg {
4293 1.1 mrg gfc_interface_sym_mapping *sym;
4294 1.1 mrg gfc_interface_sym_mapping *nextsym;
4295 1.1 mrg gfc_charlen *cl;
4296 1.1 mrg gfc_charlen *nextcl;
4297 1.1 mrg
4298 1.1 mrg for (sym = mapping->syms; sym; sym = nextsym)
4299 1.1 mrg {
4300 1.1 mrg nextsym = sym->next;
4301 1.1 mrg sym->new_sym->n.sym->formal = NULL;
4302 1.1 mrg gfc_free_symbol (sym->new_sym->n.sym);
4303 1.1 mrg gfc_free_expr (sym->expr);
4304 1.1 mrg free (sym->new_sym);
4305 1.1 mrg free (sym);
4306 1.1 mrg }
4307 1.1 mrg for (cl = mapping->charlens; cl; cl = nextcl)
4308 1.1 mrg {
4309 1.1 mrg nextcl = cl->next;
4310 1.1 mrg gfc_free_expr (cl->length);
4311 1.1 mrg free (cl);
4312 1.1 mrg }
4313 1.1 mrg }
4314 1.1 mrg
4315 1.1 mrg
4316 1.1 mrg /* Return a copy of gfc_charlen CL. Add the returned structure to
4317 1.1 mrg MAPPING so that it will be freed by gfc_free_interface_mapping. */
4318 1.1 mrg
4319 1.1 mrg static gfc_charlen *
4320 1.1 mrg gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4321 1.1 mrg gfc_charlen * cl)
4322 1.1 mrg {
4323 1.1 mrg gfc_charlen *new_charlen;
4324 1.1 mrg
4325 1.1 mrg new_charlen = gfc_get_charlen ();
4326 1.1 mrg new_charlen->next = mapping->charlens;
4327 1.1 mrg new_charlen->length = gfc_copy_expr (cl->length);
4328 1.1 mrg
4329 1.1 mrg mapping->charlens = new_charlen;
4330 1.1 mrg return new_charlen;
4331 1.1 mrg }
4332 1.1 mrg
4333 1.1 mrg
4334 1.1 mrg /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4335 1.1 mrg array variable that can be used as the actual argument for dummy
4336 1.1 mrg argument SYM. Add any initialization code to BLOCK. PACKED is as
4337 1.1 mrg for gfc_get_nodesc_array_type and DATA points to the first element
4338 1.1 mrg in the passed array. */
4339 1.1 mrg
4340 1.1 mrg static tree
4341 1.1 mrg gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4342 1.1 mrg gfc_packed packed, tree data, tree len)
4343 1.1 mrg {
4344 1.1 mrg tree type;
4345 1.1 mrg tree var;
4346 1.1 mrg
4347 1.1 mrg if (len != NULL_TREE && (TREE_CONSTANT (len) || VAR_P (len)))
4348 1.1 mrg type = gfc_get_character_type_len (sym->ts.kind, len);
4349 1.1 mrg else
4350 1.1 mrg type = gfc_typenode_for_spec (&sym->ts);
4351 1.1 mrg type = gfc_get_nodesc_array_type (type, sym->as, packed,
4352 1.1 mrg !sym->attr.target && !sym->attr.pointer
4353 1.1 mrg && !sym->attr.proc_pointer);
4354 1.1 mrg
4355 1.1 mrg var = gfc_create_var (type, "ifm");
4356 1.1 mrg gfc_add_modify (block, var, fold_convert (type, data));
4357 1.1 mrg
4358 1.1 mrg return var;
4359 1.1 mrg }
4360 1.1 mrg
4361 1.1 mrg
4362 1.1 mrg /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4363 1.1 mrg and offset of descriptorless array type TYPE given that it has the same
4364 1.1 mrg size as DESC. Add any set-up code to BLOCK. */
4365 1.1 mrg
4366 1.1 mrg static void
4367 1.1 mrg gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4368 1.1 mrg {
4369 1.1 mrg int n;
4370 1.1 mrg tree dim;
4371 1.1 mrg tree offset;
4372 1.1 mrg tree tmp;
4373 1.1 mrg
4374 1.1 mrg offset = gfc_index_zero_node;
4375 1.1 mrg for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4376 1.1 mrg {
4377 1.1 mrg dim = gfc_rank_cst[n];
4378 1.1 mrg GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4379 1.1 mrg if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4380 1.1 mrg {
4381 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n)
4382 1.1 mrg = gfc_conv_descriptor_lbound_get (desc, dim);
4383 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, n)
4384 1.1 mrg = gfc_conv_descriptor_ubound_get (desc, dim);
4385 1.1 mrg }
4386 1.1 mrg else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4387 1.1 mrg {
4388 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
4389 1.1 mrg gfc_array_index_type,
4390 1.1 mrg gfc_conv_descriptor_ubound_get (desc, dim),
4391 1.1 mrg gfc_conv_descriptor_lbound_get (desc, dim));
4392 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR,
4393 1.1 mrg gfc_array_index_type,
4394 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4395 1.1 mrg tmp = gfc_evaluate_now (tmp, block);
4396 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4397 1.1 mrg }
4398 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4399 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n),
4400 1.1 mrg GFC_TYPE_ARRAY_STRIDE (type, n));
4401 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR,
4402 1.1 mrg gfc_array_index_type, offset, tmp);
4403 1.1 mrg }
4404 1.1 mrg offset = gfc_evaluate_now (offset, block);
4405 1.1 mrg GFC_TYPE_ARRAY_OFFSET (type) = offset;
4406 1.1 mrg }
4407 1.1 mrg
4408 1.1 mrg
4409 1.1 mrg /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4410 1.1 mrg in SE. The caller may still use se->expr and se->string_length after
4411 1.1 mrg calling this function. */
4412 1.1 mrg
4413 1.1 mrg void
4414 1.1 mrg gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4415 1.1 mrg gfc_symbol * sym, gfc_se * se,
4416 1.1 mrg gfc_expr *expr)
4417 1.1 mrg {
4418 1.1 mrg gfc_interface_sym_mapping *sm;
4419 1.1 mrg tree desc;
4420 1.1 mrg tree tmp;
4421 1.1 mrg tree value;
4422 1.1 mrg gfc_symbol *new_sym;
4423 1.1 mrg gfc_symtree *root;
4424 1.1 mrg gfc_symtree *new_symtree;
4425 1.1 mrg
4426 1.1 mrg /* Create a new symbol to represent the actual argument. */
4427 1.1 mrg new_sym = gfc_new_symbol (sym->name, NULL);
4428 1.1 mrg new_sym->ts = sym->ts;
4429 1.1 mrg new_sym->as = gfc_copy_array_spec (sym->as);
4430 1.1 mrg new_sym->attr.referenced = 1;
4431 1.1 mrg new_sym->attr.dimension = sym->attr.dimension;
4432 1.1 mrg new_sym->attr.contiguous = sym->attr.contiguous;
4433 1.1 mrg new_sym->attr.codimension = sym->attr.codimension;
4434 1.1 mrg new_sym->attr.pointer = sym->attr.pointer;
4435 1.1 mrg new_sym->attr.allocatable = sym->attr.allocatable;
4436 1.1 mrg new_sym->attr.flavor = sym->attr.flavor;
4437 1.1 mrg new_sym->attr.function = sym->attr.function;
4438 1.1 mrg
4439 1.1 mrg /* Ensure that the interface is available and that
4440 1.1 mrg descriptors are passed for array actual arguments. */
4441 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE)
4442 1.1 mrg {
4443 1.1 mrg new_sym->formal = expr->symtree->n.sym->formal;
4444 1.1 mrg new_sym->attr.always_explicit
4445 1.1 mrg = expr->symtree->n.sym->attr.always_explicit;
4446 1.1 mrg }
4447 1.1 mrg
4448 1.1 mrg /* Create a fake symtree for it. */
4449 1.1 mrg root = NULL;
4450 1.1 mrg new_symtree = gfc_new_symtree (&root, sym->name);
4451 1.1 mrg new_symtree->n.sym = new_sym;
4452 1.1 mrg gcc_assert (new_symtree == root);
4453 1.1 mrg
4454 1.1 mrg /* Create a dummy->actual mapping. */
4455 1.1 mrg sm = XCNEW (gfc_interface_sym_mapping);
4456 1.1 mrg sm->next = mapping->syms;
4457 1.1 mrg sm->old = sym;
4458 1.1 mrg sm->new_sym = new_symtree;
4459 1.1 mrg sm->expr = gfc_copy_expr (expr);
4460 1.1 mrg mapping->syms = sm;
4461 1.1 mrg
4462 1.1 mrg /* Stabilize the argument's value. */
4463 1.1 mrg if (!sym->attr.function && se)
4464 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre);
4465 1.1 mrg
4466 1.1 mrg if (sym->ts.type == BT_CHARACTER)
4467 1.1 mrg {
4468 1.1 mrg /* Create a copy of the dummy argument's length. */
4469 1.1 mrg new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4470 1.1 mrg sm->expr->ts.u.cl = new_sym->ts.u.cl;
4471 1.1 mrg
4472 1.1 mrg /* If the length is specified as "*", record the length that
4473 1.1 mrg the caller is passing. We should use the callee's length
4474 1.1 mrg in all other cases. */
4475 1.1 mrg if (!new_sym->ts.u.cl->length && se)
4476 1.1 mrg {
4477 1.1 mrg se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4478 1.1 mrg new_sym->ts.u.cl->backend_decl = se->string_length;
4479 1.1 mrg }
4480 1.1 mrg }
4481 1.1 mrg
4482 1.1 mrg if (!se)
4483 1.1 mrg return;
4484 1.1 mrg
4485 1.1 mrg /* Use the passed value as-is if the argument is a function. */
4486 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE)
4487 1.1 mrg value = se->expr;
4488 1.1 mrg
4489 1.1 mrg /* If the argument is a pass-by-value scalar, use the value as is. */
4490 1.1 mrg else if (!sym->attr.dimension && sym->attr.value)
4491 1.1 mrg value = se->expr;
4492 1.1 mrg
4493 1.1 mrg /* If the argument is either a string or a pointer to a string,
4494 1.1 mrg convert it to a boundless character type. */
4495 1.1 mrg else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4496 1.1 mrg {
4497 1.1 mrg se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4498 1.1 mrg tmp = gfc_get_character_type_len (sym->ts.kind, se->string_length);
4499 1.1 mrg tmp = build_pointer_type (tmp);
4500 1.1 mrg if (sym->attr.pointer)
4501 1.1 mrg value = build_fold_indirect_ref_loc (input_location,
4502 1.1 mrg se->expr);
4503 1.1 mrg else
4504 1.1 mrg value = se->expr;
4505 1.1 mrg value = fold_convert (tmp, value);
4506 1.1 mrg }
4507 1.1 mrg
4508 1.1 mrg /* If the argument is a scalar, a pointer to an array or an allocatable,
4509 1.1 mrg dereference it. */
4510 1.1 mrg else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4511 1.1 mrg value = build_fold_indirect_ref_loc (input_location,
4512 1.1 mrg se->expr);
4513 1.1 mrg
4514 1.1 mrg /* For character(*), use the actual argument's descriptor. */
4515 1.1 mrg else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4516 1.1 mrg value = build_fold_indirect_ref_loc (input_location,
4517 1.1 mrg se->expr);
4518 1.1 mrg
4519 1.1 mrg /* If the argument is an array descriptor, use it to determine
4520 1.1 mrg information about the actual argument's shape. */
4521 1.1 mrg else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4522 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4523 1.1 mrg {
4524 1.1 mrg /* Get the actual argument's descriptor. */
4525 1.1 mrg desc = build_fold_indirect_ref_loc (input_location,
4526 1.1 mrg se->expr);
4527 1.1 mrg
4528 1.1 mrg /* Create the replacement variable. */
4529 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc);
4530 1.1 mrg value = gfc_get_interface_mapping_array (&se->pre, sym,
4531 1.1 mrg PACKED_NO, tmp,
4532 1.1 mrg se->string_length);
4533 1.1 mrg
4534 1.1 mrg /* Use DESC to work out the upper bounds, strides and offset. */
4535 1.1 mrg gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4536 1.1 mrg }
4537 1.1 mrg else
4538 1.1 mrg /* Otherwise we have a packed array. */
4539 1.1 mrg value = gfc_get_interface_mapping_array (&se->pre, sym,
4540 1.1 mrg PACKED_FULL, se->expr,
4541 1.1 mrg se->string_length);
4542 1.1 mrg
4543 1.1 mrg new_sym->backend_decl = value;
4544 1.1 mrg }
4545 1.1 mrg
4546 1.1 mrg
4547 1.1 mrg /* Called once all dummy argument mappings have been added to MAPPING,
4548 1.1 mrg but before the mapping is used to evaluate expressions. Pre-evaluate
4549 1.1 mrg the length of each argument, adding any initialization code to PRE and
4550 1.1 mrg any finalization code to POST. */
4551 1.1 mrg
4552 1.1 mrg static void
4553 1.1 mrg gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4554 1.1 mrg stmtblock_t * pre, stmtblock_t * post)
4555 1.1 mrg {
4556 1.1 mrg gfc_interface_sym_mapping *sym;
4557 1.1 mrg gfc_expr *expr;
4558 1.1 mrg gfc_se se;
4559 1.1 mrg
4560 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next)
4561 1.1 mrg if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4562 1.1 mrg && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4563 1.1 mrg {
4564 1.1 mrg expr = sym->new_sym->n.sym->ts.u.cl->length;
4565 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr);
4566 1.1 mrg gfc_init_se (&se, NULL);
4567 1.1 mrg gfc_conv_expr (&se, expr);
4568 1.1 mrg se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4569 1.1 mrg se.expr = gfc_evaluate_now (se.expr, &se.pre);
4570 1.1 mrg gfc_add_block_to_block (pre, &se.pre);
4571 1.1 mrg gfc_add_block_to_block (post, &se.post);
4572 1.1 mrg
4573 1.1 mrg sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4574 1.1 mrg }
4575 1.1 mrg }
4576 1.1 mrg
4577 1.1 mrg
4578 1.1 mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to
4579 1.1 mrg constructor C. */
4580 1.1 mrg
4581 1.1 mrg static void
4582 1.1 mrg gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4583 1.1 mrg gfc_constructor_base base)
4584 1.1 mrg {
4585 1.1 mrg gfc_constructor *c;
4586 1.1 mrg for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4587 1.1 mrg {
4588 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4589 1.1 mrg if (c->iterator)
4590 1.1 mrg {
4591 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4592 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4593 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4594 1.1 mrg }
4595 1.1 mrg }
4596 1.1 mrg }
4597 1.1 mrg
4598 1.1 mrg
4599 1.1 mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to
4600 1.1 mrg reference REF. */
4601 1.1 mrg
4602 1.1 mrg static void
4603 1.1 mrg gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4604 1.1 mrg gfc_ref * ref)
4605 1.1 mrg {
4606 1.1 mrg int n;
4607 1.1 mrg
4608 1.1 mrg for (; ref; ref = ref->next)
4609 1.1 mrg switch (ref->type)
4610 1.1 mrg {
4611 1.1 mrg case REF_ARRAY:
4612 1.1 mrg for (n = 0; n < ref->u.ar.dimen; n++)
4613 1.1 mrg {
4614 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4615 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4616 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4617 1.1 mrg }
4618 1.1 mrg break;
4619 1.1 mrg
4620 1.1 mrg case REF_COMPONENT:
4621 1.1 mrg case REF_INQUIRY:
4622 1.1 mrg break;
4623 1.1 mrg
4624 1.1 mrg case REF_SUBSTRING:
4625 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4626 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4627 1.1 mrg break;
4628 1.1 mrg }
4629 1.1 mrg }
4630 1.1 mrg
4631 1.1 mrg
4632 1.1 mrg /* Convert intrinsic function calls into result expressions. */
4633 1.1 mrg
4634 1.1 mrg static bool
4635 1.1 mrg gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4636 1.1 mrg {
4637 1.1 mrg gfc_symbol *sym;
4638 1.1 mrg gfc_expr *new_expr;
4639 1.1 mrg gfc_expr *arg1;
4640 1.1 mrg gfc_expr *arg2;
4641 1.1 mrg int d, dup;
4642 1.1 mrg
4643 1.1 mrg arg1 = expr->value.function.actual->expr;
4644 1.1 mrg if (expr->value.function.actual->next)
4645 1.1 mrg arg2 = expr->value.function.actual->next->expr;
4646 1.1 mrg else
4647 1.1 mrg arg2 = NULL;
4648 1.1 mrg
4649 1.1 mrg sym = arg1->symtree->n.sym;
4650 1.1 mrg
4651 1.1 mrg if (sym->attr.dummy)
4652 1.1 mrg return false;
4653 1.1 mrg
4654 1.1 mrg new_expr = NULL;
4655 1.1 mrg
4656 1.1 mrg switch (expr->value.function.isym->id)
4657 1.1 mrg {
4658 1.1 mrg case GFC_ISYM_LEN:
4659 1.1 mrg /* TODO figure out why this condition is necessary. */
4660 1.1 mrg if (sym->attr.function
4661 1.1 mrg && (arg1->ts.u.cl->length == NULL
4662 1.1 mrg || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4663 1.1 mrg && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4664 1.1 mrg return false;
4665 1.1 mrg
4666 1.1 mrg new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4667 1.1 mrg break;
4668 1.1 mrg
4669 1.1 mrg case GFC_ISYM_LEN_TRIM:
4670 1.1 mrg new_expr = gfc_copy_expr (arg1);
4671 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4672 1.1 mrg
4673 1.1 mrg if (!new_expr)
4674 1.1 mrg return false;
4675 1.1 mrg
4676 1.1 mrg gfc_replace_expr (arg1, new_expr);
4677 1.1 mrg return true;
4678 1.1 mrg
4679 1.1 mrg case GFC_ISYM_SIZE:
4680 1.1 mrg if (!sym->as || sym->as->rank == 0)
4681 1.1 mrg return false;
4682 1.1 mrg
4683 1.1 mrg if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4684 1.1 mrg {
4685 1.1 mrg dup = mpz_get_si (arg2->value.integer);
4686 1.1 mrg d = dup - 1;
4687 1.1 mrg }
4688 1.1 mrg else
4689 1.1 mrg {
4690 1.1 mrg dup = sym->as->rank;
4691 1.1 mrg d = 0;
4692 1.1 mrg }
4693 1.1 mrg
4694 1.1 mrg for (; d < dup; d++)
4695 1.1 mrg {
4696 1.1 mrg gfc_expr *tmp;
4697 1.1 mrg
4698 1.1 mrg if (!sym->as->upper[d] || !sym->as->lower[d])
4699 1.1 mrg {
4700 1.1 mrg gfc_free_expr (new_expr);
4701 1.1 mrg return false;
4702 1.1 mrg }
4703 1.1 mrg
4704 1.1 mrg tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4705 1.1 mrg gfc_get_int_expr (gfc_default_integer_kind,
4706 1.1 mrg NULL, 1));
4707 1.1 mrg tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4708 1.1 mrg if (new_expr)
4709 1.1 mrg new_expr = gfc_multiply (new_expr, tmp);
4710 1.1 mrg else
4711 1.1 mrg new_expr = tmp;
4712 1.1 mrg }
4713 1.1 mrg break;
4714 1.1 mrg
4715 1.1 mrg case GFC_ISYM_LBOUND:
4716 1.1 mrg case GFC_ISYM_UBOUND:
4717 1.1 mrg /* TODO These implementations of lbound and ubound do not limit if
4718 1.1 mrg the size < 0, according to F95's 13.14.53 and 13.14.113. */
4719 1.1 mrg
4720 1.1 mrg if (!sym->as || sym->as->rank == 0)
4721 1.1 mrg return false;
4722 1.1 mrg
4723 1.1 mrg if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4724 1.1 mrg d = mpz_get_si (arg2->value.integer) - 1;
4725 1.1 mrg else
4726 1.1 mrg return false;
4727 1.1 mrg
4728 1.1 mrg if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4729 1.1 mrg {
4730 1.1 mrg if (sym->as->lower[d])
4731 1.1 mrg new_expr = gfc_copy_expr (sym->as->lower[d]);
4732 1.1 mrg }
4733 1.1 mrg else
4734 1.1 mrg {
4735 1.1 mrg if (sym->as->upper[d])
4736 1.1 mrg new_expr = gfc_copy_expr (sym->as->upper[d]);
4737 1.1 mrg }
4738 1.1 mrg break;
4739 1.1 mrg
4740 1.1 mrg default:
4741 1.1 mrg break;
4742 1.1 mrg }
4743 1.1 mrg
4744 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4745 1.1 mrg if (!new_expr)
4746 1.1 mrg return false;
4747 1.1 mrg
4748 1.1 mrg gfc_replace_expr (expr, new_expr);
4749 1.1 mrg return true;
4750 1.1 mrg }
4751 1.1 mrg
4752 1.1 mrg
4753 1.1 mrg static void
4754 1.1 mrg gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4755 1.1 mrg gfc_interface_mapping * mapping)
4756 1.1 mrg {
4757 1.1 mrg gfc_formal_arglist *f;
4758 1.1 mrg gfc_actual_arglist *actual;
4759 1.1 mrg
4760 1.1 mrg actual = expr->value.function.actual;
4761 1.1 mrg f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4762 1.1 mrg
4763 1.1 mrg for (; f && actual; f = f->next, actual = actual->next)
4764 1.1 mrg {
4765 1.1 mrg if (!actual->expr)
4766 1.1 mrg continue;
4767 1.1 mrg
4768 1.1 mrg gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4769 1.1 mrg }
4770 1.1 mrg
4771 1.1 mrg if (map_expr->symtree->n.sym->attr.dimension)
4772 1.1 mrg {
4773 1.1 mrg int d;
4774 1.1 mrg gfc_array_spec *as;
4775 1.1 mrg
4776 1.1 mrg as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4777 1.1 mrg
4778 1.1 mrg for (d = 0; d < as->rank; d++)
4779 1.1 mrg {
4780 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4781 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4782 1.1 mrg }
4783 1.1 mrg
4784 1.1 mrg expr->value.function.esym->as = as;
4785 1.1 mrg }
4786 1.1 mrg
4787 1.1 mrg if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4788 1.1 mrg {
4789 1.1 mrg expr->value.function.esym->ts.u.cl->length
4790 1.1 mrg = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4791 1.1 mrg
4792 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping,
4793 1.1 mrg expr->value.function.esym->ts.u.cl->length);
4794 1.1 mrg }
4795 1.1 mrg }
4796 1.1 mrg
4797 1.1 mrg
4798 1.1 mrg /* EXPR is a copy of an expression that appeared in the interface
4799 1.1 mrg associated with MAPPING. Walk it recursively looking for references to
4800 1.1 mrg dummy arguments that MAPPING maps to actual arguments. Replace each such
4801 1.1 mrg reference with a reference to the associated actual argument. */
4802 1.1 mrg
4803 1.1 mrg static void
4804 1.1 mrg gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4805 1.1 mrg gfc_expr * expr)
4806 1.1 mrg {
4807 1.1 mrg gfc_interface_sym_mapping *sym;
4808 1.1 mrg gfc_actual_arglist *actual;
4809 1.1 mrg
4810 1.1 mrg if (!expr)
4811 1.1 mrg return;
4812 1.1 mrg
4813 1.1 mrg /* Copying an expression does not copy its length, so do that here. */
4814 1.1 mrg if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4815 1.1 mrg {
4816 1.1 mrg expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4817 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4818 1.1 mrg }
4819 1.1 mrg
4820 1.1 mrg /* Apply the mapping to any references. */
4821 1.1 mrg gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4822 1.1 mrg
4823 1.1 mrg /* ...and to the expression's symbol, if it has one. */
4824 1.1 mrg /* TODO Find out why the condition on expr->symtree had to be moved into
4825 1.1 mrg the loop rather than being outside it, as originally. */
4826 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next)
4827 1.1 mrg if (expr->symtree && sym->old == expr->symtree->n.sym)
4828 1.1 mrg {
4829 1.1 mrg if (sym->new_sym->n.sym->backend_decl)
4830 1.1 mrg expr->symtree = sym->new_sym;
4831 1.1 mrg else if (sym->expr)
4832 1.1 mrg gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4833 1.1 mrg }
4834 1.1 mrg
4835 1.1 mrg /* ...and to subexpressions in expr->value. */
4836 1.1 mrg switch (expr->expr_type)
4837 1.1 mrg {
4838 1.1 mrg case EXPR_VARIABLE:
4839 1.1 mrg case EXPR_CONSTANT:
4840 1.1 mrg case EXPR_NULL:
4841 1.1 mrg case EXPR_SUBSTRING:
4842 1.1 mrg break;
4843 1.1 mrg
4844 1.1 mrg case EXPR_OP:
4845 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4846 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4847 1.1 mrg break;
4848 1.1 mrg
4849 1.1 mrg case EXPR_FUNCTION:
4850 1.1 mrg for (actual = expr->value.function.actual; actual; actual = actual->next)
4851 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4852 1.1 mrg
4853 1.1 mrg if (expr->value.function.esym == NULL
4854 1.1 mrg && expr->value.function.isym != NULL
4855 1.1 mrg && expr->value.function.actual
4856 1.1 mrg && expr->value.function.actual->expr
4857 1.1 mrg && expr->value.function.actual->expr->symtree
4858 1.1 mrg && gfc_map_intrinsic_function (expr, mapping))
4859 1.1 mrg break;
4860 1.1 mrg
4861 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next)
4862 1.1 mrg if (sym->old == expr->value.function.esym)
4863 1.1 mrg {
4864 1.1 mrg expr->value.function.esym = sym->new_sym->n.sym;
4865 1.1 mrg gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4866 1.1 mrg expr->value.function.esym->result = sym->new_sym->n.sym;
4867 1.1 mrg }
4868 1.1 mrg break;
4869 1.1 mrg
4870 1.1 mrg case EXPR_ARRAY:
4871 1.1 mrg case EXPR_STRUCTURE:
4872 1.1 mrg gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4873 1.1 mrg break;
4874 1.1 mrg
4875 1.1 mrg case EXPR_COMPCALL:
4876 1.1 mrg case EXPR_PPC:
4877 1.1 mrg case EXPR_UNKNOWN:
4878 1.1 mrg gcc_unreachable ();
4879 1.1 mrg break;
4880 1.1 mrg }
4881 1.1 mrg
4882 1.1 mrg return;
4883 1.1 mrg }
4884 1.1 mrg
4885 1.1 mrg
4886 1.1 mrg /* Evaluate interface expression EXPR using MAPPING. Store the result
4887 1.1 mrg in SE. */
4888 1.1 mrg
4889 1.1 mrg void
4890 1.1 mrg gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4891 1.1 mrg gfc_se * se, gfc_expr * expr)
4892 1.1 mrg {
4893 1.1 mrg expr = gfc_copy_expr (expr);
4894 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr);
4895 1.1 mrg gfc_conv_expr (se, expr);
4896 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre);
4897 1.1 mrg gfc_free_expr (expr);
4898 1.1 mrg }
4899 1.1 mrg
4900 1.1 mrg
4901 1.1 mrg /* Returns a reference to a temporary array into which a component of
4902 1.1 mrg an actual argument derived type array is copied and then returned
4903 1.1 mrg after the function call. */
4904 1.1 mrg void
4905 1.1 mrg gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4906 1.1 mrg sym_intent intent, bool formal_ptr,
4907 1.1 mrg const gfc_symbol *fsym, const char *proc_name,
4908 1.1 mrg gfc_symbol *sym, bool check_contiguous)
4909 1.1 mrg {
4910 1.1 mrg gfc_se lse;
4911 1.1 mrg gfc_se rse;
4912 1.1 mrg gfc_ss *lss;
4913 1.1 mrg gfc_ss *rss;
4914 1.1 mrg gfc_loopinfo loop;
4915 1.1 mrg gfc_loopinfo loop2;
4916 1.1 mrg gfc_array_info *info;
4917 1.1 mrg tree offset;
4918 1.1 mrg tree tmp_index;
4919 1.1 mrg tree tmp;
4920 1.1 mrg tree base_type;
4921 1.1 mrg tree size;
4922 1.1 mrg stmtblock_t body;
4923 1.1 mrg int n;
4924 1.1 mrg int dimen;
4925 1.1 mrg gfc_se work_se;
4926 1.1 mrg gfc_se *parmse;
4927 1.1 mrg bool pass_optional;
4928 1.1 mrg
4929 1.1 mrg pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4930 1.1 mrg
4931 1.1 mrg if (pass_optional || check_contiguous)
4932 1.1 mrg {
4933 1.1 mrg gfc_init_se (&work_se, NULL);
4934 1.1 mrg parmse = &work_se;
4935 1.1 mrg }
4936 1.1 mrg else
4937 1.1 mrg parmse = se;
4938 1.1 mrg
4939 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4940 1.1 mrg {
4941 1.1 mrg /* We will create a temporary array, so let us warn. */
4942 1.1 mrg char * msg;
4943 1.1 mrg
4944 1.1 mrg if (fsym && proc_name)
4945 1.1 mrg msg = xasprintf ("An array temporary was created for argument "
4946 1.1 mrg "'%s' of procedure '%s'", fsym->name, proc_name);
4947 1.1 mrg else
4948 1.1 mrg msg = xasprintf ("An array temporary was created");
4949 1.1 mrg
4950 1.1 mrg tmp = build_int_cst (logical_type_node, 1);
4951 1.1 mrg gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4952 1.1 mrg &expr->where, msg);
4953 1.1 mrg free (msg);
4954 1.1 mrg }
4955 1.1 mrg
4956 1.1 mrg gfc_init_se (&lse, NULL);
4957 1.1 mrg gfc_init_se (&rse, NULL);
4958 1.1 mrg
4959 1.1 mrg /* Walk the argument expression. */
4960 1.1 mrg rss = gfc_walk_expr (expr);
4961 1.1 mrg
4962 1.1 mrg gcc_assert (rss != gfc_ss_terminator);
4963 1.1 mrg
4964 1.1 mrg /* Initialize the scalarizer. */
4965 1.1 mrg gfc_init_loopinfo (&loop);
4966 1.1 mrg gfc_add_ss_to_loop (&loop, rss);
4967 1.1 mrg
4968 1.1 mrg /* Calculate the bounds of the scalarization. */
4969 1.1 mrg gfc_conv_ss_startstride (&loop);
4970 1.1 mrg
4971 1.1 mrg /* Build an ss for the temporary. */
4972 1.1 mrg if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4973 1.1 mrg gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4974 1.1 mrg
4975 1.1 mrg base_type = gfc_typenode_for_spec (&expr->ts);
4976 1.1 mrg if (GFC_ARRAY_TYPE_P (base_type)
4977 1.1 mrg || GFC_DESCRIPTOR_TYPE_P (base_type))
4978 1.1 mrg base_type = gfc_get_element_type (base_type);
4979 1.1 mrg
4980 1.1 mrg if (expr->ts.type == BT_CLASS)
4981 1.1 mrg base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4982 1.1 mrg
4983 1.1 mrg loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4984 1.1 mrg ? expr->ts.u.cl->backend_decl
4985 1.1 mrg : NULL),
4986 1.1 mrg loop.dimen);
4987 1.1 mrg
4988 1.1 mrg parmse->string_length = loop.temp_ss->info->string_length;
4989 1.1 mrg
4990 1.1 mrg /* Associate the SS with the loop. */
4991 1.1 mrg gfc_add_ss_to_loop (&loop, loop.temp_ss);
4992 1.1 mrg
4993 1.1 mrg /* Setup the scalarizing loops. */
4994 1.1 mrg gfc_conv_loop_setup (&loop, &expr->where);
4995 1.1 mrg
4996 1.1 mrg /* Pass the temporary descriptor back to the caller. */
4997 1.1 mrg info = &loop.temp_ss->info->data.array;
4998 1.1 mrg parmse->expr = info->descriptor;
4999 1.1 mrg
5000 1.1 mrg /* Setup the gfc_se structures. */
5001 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop);
5002 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop);
5003 1.1 mrg
5004 1.1 mrg rse.ss = rss;
5005 1.1 mrg lse.ss = loop.temp_ss;
5006 1.1 mrg gfc_mark_ss_chain_used (rss, 1);
5007 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 1);
5008 1.1 mrg
5009 1.1 mrg /* Start the scalarized loop body. */
5010 1.1 mrg gfc_start_scalarized_body (&loop, &body);
5011 1.1 mrg
5012 1.1 mrg /* Translate the expression. */
5013 1.1 mrg gfc_conv_expr (&rse, expr);
5014 1.1 mrg
5015 1.1 mrg /* Reset the offset for the function call since the loop
5016 1.1 mrg is zero based on the data pointer. Note that the temp
5017 1.1 mrg comes first in the loop chain since it is added second. */
5018 1.1 mrg if (gfc_is_class_array_function (expr))
5019 1.1 mrg {
5020 1.1 mrg tmp = loop.ss->loop_chain->info->data.array.descriptor;
5021 1.1 mrg gfc_conv_descriptor_offset_set (&loop.pre, tmp,
5022 1.1 mrg gfc_index_zero_node);
5023 1.1 mrg }
5024 1.1 mrg
5025 1.1 mrg gfc_conv_tmp_array_ref (&lse);
5026 1.1 mrg
5027 1.1 mrg if (intent != INTENT_OUT)
5028 1.1 mrg {
5029 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
5030 1.1 mrg gfc_add_expr_to_block (&body, tmp);
5031 1.1 mrg gcc_assert (rse.ss == gfc_ss_terminator);
5032 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body);
5033 1.1 mrg }
5034 1.1 mrg else
5035 1.1 mrg {
5036 1.1 mrg /* Make sure that the temporary declaration survives by merging
5037 1.1 mrg all the loop declarations into the current context. */
5038 1.1 mrg for (n = 0; n < loop.dimen; n++)
5039 1.1 mrg {
5040 1.1 mrg gfc_merge_block_scope (&body);
5041 1.1 mrg body = loop.code[loop.order[n]];
5042 1.1 mrg }
5043 1.1 mrg gfc_merge_block_scope (&body);
5044 1.1 mrg }
5045 1.1 mrg
5046 1.1 mrg /* Add the post block after the second loop, so that any
5047 1.1 mrg freeing of allocated memory is done at the right time. */
5048 1.1 mrg gfc_add_block_to_block (&parmse->pre, &loop.pre);
5049 1.1 mrg
5050 1.1 mrg /**********Copy the temporary back again.*********/
5051 1.1 mrg
5052 1.1 mrg gfc_init_se (&lse, NULL);
5053 1.1 mrg gfc_init_se (&rse, NULL);
5054 1.1 mrg
5055 1.1 mrg /* Walk the argument expression. */
5056 1.1 mrg lss = gfc_walk_expr (expr);
5057 1.1 mrg rse.ss = loop.temp_ss;
5058 1.1 mrg lse.ss = lss;
5059 1.1 mrg
5060 1.1 mrg /* Initialize the scalarizer. */
5061 1.1 mrg gfc_init_loopinfo (&loop2);
5062 1.1 mrg gfc_add_ss_to_loop (&loop2, lss);
5063 1.1 mrg
5064 1.1 mrg dimen = rse.ss->dimen;
5065 1.1 mrg
5066 1.1 mrg /* Skip the write-out loop for this case. */
5067 1.1 mrg if (gfc_is_class_array_function (expr))
5068 1.1 mrg goto class_array_fcn;
5069 1.1 mrg
5070 1.1 mrg /* Calculate the bounds of the scalarization. */
5071 1.1 mrg gfc_conv_ss_startstride (&loop2);
5072 1.1 mrg
5073 1.1 mrg /* Setup the scalarizing loops. */
5074 1.1 mrg gfc_conv_loop_setup (&loop2, &expr->where);
5075 1.1 mrg
5076 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop2);
5077 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop2);
5078 1.1 mrg
5079 1.1 mrg gfc_mark_ss_chain_used (lss, 1);
5080 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 1);
5081 1.1 mrg
5082 1.1 mrg /* Declare the variable to hold the temporary offset and start the
5083 1.1 mrg scalarized loop body. */
5084 1.1 mrg offset = gfc_create_var (gfc_array_index_type, NULL);
5085 1.1 mrg gfc_start_scalarized_body (&loop2, &body);
5086 1.1 mrg
5087 1.1 mrg /* Build the offsets for the temporary from the loop variables. The
5088 1.1 mrg temporary array has lbounds of zero and strides of one in all
5089 1.1 mrg dimensions, so this is very simple. The offset is only computed
5090 1.1 mrg outside the innermost loop, so the overall transfer could be
5091 1.1 mrg optimized further. */
5092 1.1 mrg info = &rse.ss->info->data.array;
5093 1.1 mrg
5094 1.1 mrg tmp_index = gfc_index_zero_node;
5095 1.1 mrg for (n = dimen - 1; n > 0; n--)
5096 1.1 mrg {
5097 1.1 mrg tree tmp_str;
5098 1.1 mrg tmp = rse.loop->loopvar[n];
5099 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5100 1.1 mrg tmp, rse.loop->from[n]);
5101 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5102 1.1 mrg tmp, tmp_index);
5103 1.1 mrg
5104 1.1 mrg tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5105 1.1 mrg gfc_array_index_type,
5106 1.1 mrg rse.loop->to[n-1], rse.loop->from[n-1]);
5107 1.1 mrg tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5108 1.1 mrg gfc_array_index_type,
5109 1.1 mrg tmp_str, gfc_index_one_node);
5110 1.1 mrg
5111 1.1 mrg tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5112 1.1 mrg gfc_array_index_type, tmp, tmp_str);
5113 1.1 mrg }
5114 1.1 mrg
5115 1.1 mrg tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5116 1.1 mrg gfc_array_index_type,
5117 1.1 mrg tmp_index, rse.loop->from[0]);
5118 1.1 mrg gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
5119 1.1 mrg
5120 1.1 mrg tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5121 1.1 mrg gfc_array_index_type,
5122 1.1 mrg rse.loop->loopvar[0], offset);
5123 1.1 mrg
5124 1.1 mrg /* Now use the offset for the reference. */
5125 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
5126 1.1 mrg info->data);
5127 1.1 mrg rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
5128 1.1 mrg
5129 1.1 mrg if (expr->ts.type == BT_CHARACTER)
5130 1.1 mrg rse.string_length = expr->ts.u.cl->backend_decl;
5131 1.1 mrg
5132 1.1 mrg gfc_conv_expr (&lse, expr);
5133 1.1 mrg
5134 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator);
5135 1.1 mrg
5136 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
5137 1.1 mrg gfc_add_expr_to_block (&body, tmp);
5138 1.1 mrg
5139 1.1 mrg /* Generate the copying loops. */
5140 1.1 mrg gfc_trans_scalarizing_loops (&loop2, &body);
5141 1.1 mrg
5142 1.1 mrg /* Wrap the whole thing up by adding the second loop to the post-block
5143 1.1 mrg and following it by the post-block of the first loop. In this way,
5144 1.1 mrg if the temporary needs freeing, it is done after use! */
5145 1.1 mrg if (intent != INTENT_IN)
5146 1.1 mrg {
5147 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop2.pre);
5148 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop2.post);
5149 1.1 mrg }
5150 1.1 mrg
5151 1.1 mrg class_array_fcn:
5152 1.1 mrg
5153 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop.post);
5154 1.1 mrg
5155 1.1 mrg gfc_cleanup_loop (&loop);
5156 1.1 mrg gfc_cleanup_loop (&loop2);
5157 1.1 mrg
5158 1.1 mrg /* Pass the string length to the argument expression. */
5159 1.1 mrg if (expr->ts.type == BT_CHARACTER)
5160 1.1 mrg parmse->string_length = expr->ts.u.cl->backend_decl;
5161 1.1 mrg
5162 1.1 mrg /* Determine the offset for pointer formal arguments and set the
5163 1.1 mrg lbounds to one. */
5164 1.1 mrg if (formal_ptr)
5165 1.1 mrg {
5166 1.1 mrg size = gfc_index_one_node;
5167 1.1 mrg offset = gfc_index_zero_node;
5168 1.1 mrg for (n = 0; n < dimen; n++)
5169 1.1 mrg {
5170 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5171 1.1 mrg gfc_rank_cst[n]);
5172 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR,
5173 1.1 mrg gfc_array_index_type, tmp,
5174 1.1 mrg gfc_index_one_node);
5175 1.1 mrg gfc_conv_descriptor_ubound_set (&parmse->pre,
5176 1.1 mrg parmse->expr,
5177 1.1 mrg gfc_rank_cst[n],
5178 1.1 mrg tmp);
5179 1.1 mrg gfc_conv_descriptor_lbound_set (&parmse->pre,
5180 1.1 mrg parmse->expr,
5181 1.1 mrg gfc_rank_cst[n],
5182 1.1 mrg gfc_index_one_node);
5183 1.1 mrg size = gfc_evaluate_now (size, &parmse->pre);
5184 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR,
5185 1.1 mrg gfc_array_index_type,
5186 1.1 mrg offset, size);
5187 1.1 mrg offset = gfc_evaluate_now (offset, &parmse->pre);
5188 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
5189 1.1 mrg gfc_array_index_type,
5190 1.1 mrg rse.loop->to[n], rse.loop->from[n]);
5191 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR,
5192 1.1 mrg gfc_array_index_type,
5193 1.1 mrg tmp, gfc_index_one_node);
5194 1.1 mrg size = fold_build2_loc (input_location, MULT_EXPR,
5195 1.1 mrg gfc_array_index_type, size, tmp);
5196 1.1 mrg }
5197 1.1 mrg
5198 1.1 mrg gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5199 1.1 mrg offset);
5200 1.1 mrg }
5201 1.1 mrg
5202 1.1 mrg /* We want either the address for the data or the address of the descriptor,
5203 1.1 mrg depending on the mode of passing array arguments. */
5204 1.1 mrg if (g77)
5205 1.1 mrg parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5206 1.1 mrg else
5207 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5208 1.1 mrg
5209 1.1 mrg /* Basically make this into
5210 1.1 mrg
5211 1.1 mrg if (present)
5212 1.1 mrg {
5213 1.1 mrg if (contiguous)
5214 1.1 mrg {
5215 1.1 mrg pointer = a;
5216 1.1 mrg }
5217 1.1 mrg else
5218 1.1 mrg {
5219 1.1 mrg parmse->pre();
5220 1.1 mrg pointer = parmse->expr;
5221 1.1 mrg }
5222 1.1 mrg }
5223 1.1 mrg else
5224 1.1 mrg pointer = NULL;
5225 1.1 mrg
5226 1.1 mrg foo (pointer);
5227 1.1 mrg if (present && !contiguous)
5228 1.1 mrg se->post();
5229 1.1 mrg
5230 1.1 mrg */
5231 1.1 mrg
5232 1.1 mrg if (pass_optional || check_contiguous)
5233 1.1 mrg {
5234 1.1 mrg tree type;
5235 1.1 mrg stmtblock_t else_block;
5236 1.1 mrg tree pre_stmts, post_stmts;
5237 1.1 mrg tree pointer;
5238 1.1 mrg tree else_stmt;
5239 1.1 mrg tree present_var = NULL_TREE;
5240 1.1 mrg tree cont_var = NULL_TREE;
5241 1.1 mrg tree post_cond;
5242 1.1 mrg
5243 1.1 mrg type = TREE_TYPE (parmse->expr);
5244 1.1 mrg if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
5245 1.1 mrg type = TREE_TYPE (type);
5246 1.1 mrg pointer = gfc_create_var (type, "arg_ptr");
5247 1.1 mrg
5248 1.1 mrg if (check_contiguous)
5249 1.1 mrg {
5250 1.1 mrg gfc_se cont_se, array_se;
5251 1.1 mrg stmtblock_t if_block, else_block;
5252 1.1 mrg tree if_stmt, else_stmt;
5253 1.1 mrg mpz_t size;
5254 1.1 mrg bool size_set;
5255 1.1 mrg
5256 1.1 mrg cont_var = gfc_create_var (boolean_type_node, "contiguous");
5257 1.1 mrg
5258 1.1 mrg /* If the size is known to be one at compile-time, set
5259 1.1 mrg cont_var to true unconditionally. This may look
5260 1.1 mrg inelegant, but we're only doing this during
5261 1.1 mrg optimization, so the statements will be optimized away,
5262 1.1 mrg and this saves complexity here. */
5263 1.1 mrg
5264 1.1 mrg size_set = gfc_array_size (expr, &size);
5265 1.1 mrg if (size_set && mpz_cmp_ui (size, 1) == 0)
5266 1.1 mrg {
5267 1.1 mrg gfc_add_modify (&se->pre, cont_var,
5268 1.1 mrg build_one_cst (boolean_type_node));
5269 1.1 mrg }
5270 1.1 mrg else
5271 1.1 mrg {
5272 1.1 mrg /* cont_var = is_contiguous (expr); . */
5273 1.1 mrg gfc_init_se (&cont_se, parmse);
5274 1.1 mrg gfc_conv_is_contiguous_expr (&cont_se, expr);
5275 1.1 mrg gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5276 1.1 mrg gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5277 1.1 mrg gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5278 1.1 mrg }
5279 1.1 mrg
5280 1.1 mrg if (size_set)
5281 1.1 mrg mpz_clear (size);
5282 1.1 mrg
5283 1.1 mrg /* arrayse->expr = descriptor of a. */
5284 1.1 mrg gfc_init_se (&array_se, se);
5285 1.1 mrg gfc_conv_expr_descriptor (&array_se, expr);
5286 1.1 mrg gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5287 1.1 mrg gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5288 1.1 mrg
5289 1.1 mrg /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } . */
5290 1.1 mrg gfc_init_block (&if_block);
5291 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
5292 1.1 mrg gfc_add_modify (&if_block, pointer, array_se.expr);
5293 1.1 mrg else
5294 1.1 mrg {
5295 1.1 mrg tmp = gfc_conv_array_data (array_se.expr);
5296 1.1 mrg tmp = fold_convert (type, tmp);
5297 1.1 mrg gfc_add_modify (&if_block, pointer, tmp);
5298 1.1 mrg }
5299 1.1 mrg if_stmt = gfc_finish_block (&if_block);
5300 1.1 mrg
5301 1.1 mrg /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5302 1.1 mrg gfc_init_block (&else_block);
5303 1.1 mrg gfc_add_block_to_block (&else_block, &parmse->pre);
5304 1.1 mrg tmp = (GFC_DESCRIPTOR_TYPE_P (type)
5305 1.1 mrg ? build_fold_indirect_ref_loc (input_location, parmse->expr)
5306 1.1 mrg : parmse->expr);
5307 1.1 mrg gfc_add_modify (&else_block, pointer, tmp);
5308 1.1 mrg else_stmt = gfc_finish_block (&else_block);
5309 1.1 mrg
5310 1.1 mrg /* And put the above into an if statement. */
5311 1.1 mrg pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5312 1.1 mrg gfc_likely (cont_var,
5313 1.1 mrg PRED_FORTRAN_CONTIGUOUS),
5314 1.1 mrg if_stmt, else_stmt);
5315 1.1 mrg }
5316 1.1 mrg else
5317 1.1 mrg {
5318 1.1 mrg /* pointer = pramse->expr; . */
5319 1.1 mrg gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5320 1.1 mrg pre_stmts = gfc_finish_block (&parmse->pre);
5321 1.1 mrg }
5322 1.1 mrg
5323 1.1 mrg if (pass_optional)
5324 1.1 mrg {
5325 1.1 mrg present_var = gfc_create_var (boolean_type_node, "present");
5326 1.1 mrg
5327 1.1 mrg /* present_var = present(sym); . */
5328 1.1 mrg tmp = gfc_conv_expr_present (sym);
5329 1.1 mrg tmp = fold_convert (boolean_type_node, tmp);
5330 1.1 mrg gfc_add_modify (&se->pre, present_var, tmp);
5331 1.1 mrg
5332 1.1 mrg /* else_stmt = { pointer = NULL; } . */
5333 1.1 mrg gfc_init_block (&else_block);
5334 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
5335 1.1 mrg gfc_conv_descriptor_data_set (&else_block, pointer,
5336 1.1 mrg null_pointer_node);
5337 1.1 mrg else
5338 1.1 mrg gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5339 1.1 mrg else_stmt = gfc_finish_block (&else_block);
5340 1.1 mrg
5341 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5342 1.1 mrg gfc_likely (present_var,
5343 1.1 mrg PRED_FORTRAN_ABSENT_DUMMY),
5344 1.1 mrg pre_stmts, else_stmt);
5345 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
5346 1.1 mrg }
5347 1.1 mrg else
5348 1.1 mrg gfc_add_expr_to_block (&se->pre, pre_stmts);
5349 1.1 mrg
5350 1.1 mrg post_stmts = gfc_finish_block (&parmse->post);
5351 1.1 mrg
5352 1.1 mrg /* Put together the post stuff, plus the optional
5353 1.1 mrg deallocation. */
5354 1.1 mrg if (check_contiguous)
5355 1.1 mrg {
5356 1.1 mrg /* !cont_var. */
5357 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5358 1.1 mrg cont_var,
5359 1.1 mrg build_zero_cst (boolean_type_node));
5360 1.1 mrg tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5361 1.1 mrg
5362 1.1 mrg if (pass_optional)
5363 1.1 mrg {
5364 1.1 mrg tree present_likely = gfc_likely (present_var,
5365 1.1 mrg PRED_FORTRAN_ABSENT_DUMMY);
5366 1.1 mrg post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5367 1.1 mrg boolean_type_node, present_likely,
5368 1.1 mrg tmp);
5369 1.1 mrg }
5370 1.1 mrg else
5371 1.1 mrg post_cond = tmp;
5372 1.1 mrg }
5373 1.1 mrg else
5374 1.1 mrg {
5375 1.1 mrg gcc_assert (pass_optional);
5376 1.1 mrg post_cond = present_var;
5377 1.1 mrg }
5378 1.1 mrg
5379 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
5380 1.1 mrg post_stmts, build_empty_stmt (input_location));
5381 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
5382 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
5383 1.1 mrg {
5384 1.1 mrg type = TREE_TYPE (parmse->expr);
5385 1.1 mrg if (POINTER_TYPE_P (type))
5386 1.1 mrg {
5387 1.1 mrg pointer = gfc_build_addr_expr (type, pointer);
5388 1.1 mrg if (pass_optional)
5389 1.1 mrg {
5390 1.1 mrg tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY);
5391 1.1 mrg pointer = fold_build3_loc (input_location, COND_EXPR, type,
5392 1.1 mrg tmp, pointer,
5393 1.1 mrg fold_convert (type,
5394 1.1 mrg null_pointer_node));
5395 1.1 mrg }
5396 1.1 mrg }
5397 1.1 mrg else
5398 1.1 mrg gcc_assert (!pass_optional);
5399 1.1 mrg }
5400 1.1 mrg se->expr = pointer;
5401 1.1 mrg }
5402 1.1 mrg
5403 1.1 mrg return;
5404 1.1 mrg }
5405 1.1 mrg
5406 1.1 mrg
5407 1.1 mrg /* Generate the code for argument list functions. */
5408 1.1 mrg
5409 1.1 mrg static void
5410 1.1 mrg conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5411 1.1 mrg {
5412 1.1 mrg /* Pass by value for g77 %VAL(arg), pass the address
5413 1.1 mrg indirectly for %LOC, else by reference. Thus %REF
5414 1.1 mrg is a "do-nothing" and %LOC is the same as an F95
5415 1.1 mrg pointer. */
5416 1.1 mrg if (strcmp (name, "%VAL") == 0)
5417 1.1 mrg gfc_conv_expr (se, expr);
5418 1.1 mrg else if (strcmp (name, "%LOC") == 0)
5419 1.1 mrg {
5420 1.1 mrg gfc_conv_expr_reference (se, expr);
5421 1.1 mrg se->expr = gfc_build_addr_expr (NULL, se->expr);
5422 1.1 mrg }
5423 1.1 mrg else if (strcmp (name, "%REF") == 0)
5424 1.1 mrg gfc_conv_expr_reference (se, expr);
5425 1.1 mrg else
5426 1.1 mrg gfc_error ("Unknown argument list function at %L", &expr->where);
5427 1.1 mrg }
5428 1.1 mrg
5429 1.1 mrg
5430 1.1 mrg /* This function tells whether the middle-end representation of the expression
5431 1.1 mrg E given as input may point to data otherwise accessible through a variable
5432 1.1 mrg (sub-)reference.
5433 1.1 mrg It is assumed that the only expressions that may alias are variables,
5434 1.1 mrg and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5435 1.1 mrg may alias.
5436 1.1 mrg This function is used to decide whether freeing an expression's allocatable
5437 1.1 mrg components is safe or should be avoided.
5438 1.1 mrg
5439 1.1 mrg If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5440 1.1 mrg its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5441 1.1 mrg is necessary because for array constructors, aliasing depends on how
5442 1.1 mrg the array is used:
5443 1.1 mrg - If E is an array constructor used as argument to an elemental procedure,
5444 1.1 mrg the array, which is generated through shallow copy by the scalarizer,
5445 1.1 mrg is used directly and can alias the expressions it was copied from.
5446 1.1 mrg - If E is an array constructor used as argument to a non-elemental
5447 1.1 mrg procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5448 1.1 mrg the array as in the previous case, but then that array is used
5449 1.1 mrg to initialize a new descriptor through deep copy. There is no alias
5450 1.1 mrg possible in that case.
5451 1.1 mrg Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5452 1.1 mrg above. */
5453 1.1 mrg
5454 1.1 mrg static bool
5455 1.1 mrg expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5456 1.1 mrg {
5457 1.1 mrg gfc_constructor *c;
5458 1.1 mrg
5459 1.1 mrg if (e->expr_type == EXPR_VARIABLE)
5460 1.1 mrg return true;
5461 1.1 mrg else if (e->expr_type == EXPR_FUNCTION)
5462 1.1 mrg {
5463 1.1 mrg gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5464 1.1 mrg
5465 1.1 mrg if (proc_ifc->result != NULL
5466 1.1 mrg && ((proc_ifc->result->ts.type == BT_CLASS
5467 1.1 mrg && proc_ifc->result->ts.u.derived->attr.is_class
5468 1.1 mrg && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5469 1.1 mrg || proc_ifc->result->attr.pointer))
5470 1.1 mrg return true;
5471 1.1 mrg else
5472 1.1 mrg return false;
5473 1.1 mrg }
5474 1.1 mrg else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5475 1.1 mrg return false;
5476 1.1 mrg
5477 1.1 mrg for (c = gfc_constructor_first (e->value.constructor);
5478 1.1 mrg c; c = gfc_constructor_next (c))
5479 1.1 mrg if (c->expr
5480 1.1 mrg && expr_may_alias_variables (c->expr, array_may_alias))
5481 1.1 mrg return true;
5482 1.1 mrg
5483 1.1 mrg return false;
5484 1.1 mrg }
5485 1.1 mrg
5486 1.1 mrg
5487 1.1 mrg /* A helper function to set the dtype for unallocated or unassociated
5488 1.1 mrg entities. */
5489 1.1 mrg
5490 1.1 mrg static void
5491 1.1 mrg set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5492 1.1 mrg {
5493 1.1 mrg tree tmp;
5494 1.1 mrg tree desc;
5495 1.1 mrg tree cond;
5496 1.1 mrg tree type;
5497 1.1 mrg stmtblock_t block;
5498 1.1 mrg
5499 1.1 mrg /* TODO Figure out how to handle optional dummies. */
5500 1.1 mrg if (e && e->expr_type == EXPR_VARIABLE
5501 1.1 mrg && e->symtree->n.sym->attr.optional)
5502 1.1 mrg return;
5503 1.1 mrg
5504 1.1 mrg desc = parmse->expr;
5505 1.1 mrg if (desc == NULL_TREE)
5506 1.1 mrg return;
5507 1.1 mrg
5508 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (desc)))
5509 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, desc);
5510 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (desc)))
5511 1.1 mrg desc = gfc_class_data_get (desc);
5512 1.1 mrg if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5513 1.1 mrg return;
5514 1.1 mrg
5515 1.1 mrg gfc_init_block (&block);
5516 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc);
5517 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR,
5518 1.1 mrg logical_type_node, tmp,
5519 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0));
5520 1.1 mrg tmp = gfc_conv_descriptor_dtype (desc);
5521 1.1 mrg type = gfc_get_element_type (TREE_TYPE (desc));
5522 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5523 1.1 mrg TREE_TYPE (tmp), tmp,
5524 1.1 mrg gfc_get_dtype_rank_type (e->rank, type));
5525 1.1 mrg gfc_add_expr_to_block (&block, tmp);
5526 1.1 mrg cond = build3_v (COND_EXPR, cond,
5527 1.1 mrg gfc_finish_block (&block),
5528 1.1 mrg build_empty_stmt (input_location));
5529 1.1 mrg gfc_add_expr_to_block (&parmse->pre, cond);
5530 1.1 mrg }
5531 1.1 mrg
5532 1.1 mrg
5533 1.1 mrg
5534 1.1 mrg /* Provide an interface between gfortran array descriptors and the F2018:18.4
5535 1.1 mrg ISO_Fortran_binding array descriptors. */
5536 1.1 mrg
5537 1.1 mrg static void
5538 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5539 1.1 mrg {
5540 1.1 mrg stmtblock_t block, block2;
5541 1.1 mrg tree cfi, gfc, tmp, tmp2;
5542 1.1 mrg tree present = NULL;
5543 1.1 mrg tree gfc_strlen = NULL;
5544 1.1 mrg tree rank;
5545 1.1 mrg gfc_se se;
5546 1.1 mrg
5547 1.1 mrg if (fsym->attr.optional
5548 1.1 mrg && e->expr_type == EXPR_VARIABLE
5549 1.1 mrg && e->symtree->n.sym->attr.optional)
5550 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym);
5551 1.1 mrg
5552 1.1 mrg gfc_init_block (&block);
5553 1.1 mrg
5554 1.1 mrg /* Convert original argument to a tree. */
5555 1.1 mrg gfc_init_se (&se, NULL);
5556 1.1 mrg if (e->rank == 0)
5557 1.1 mrg {
5558 1.1 mrg se.want_pointer = 1;
5559 1.1 mrg gfc_conv_expr (&se, e);
5560 1.1 mrg gfc = se.expr;
5561 1.1 mrg /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */
5562 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
5563 1.1 mrg gfc = gfc_build_addr_expr (NULL, gfc);
5564 1.1 mrg }
5565 1.1 mrg else
5566 1.1 mrg {
5567 1.1 mrg /* If the actual argument can be noncontiguous, copy-in/out is required,
5568 1.1 mrg if the dummy has either the CONTIGUOUS attribute or is an assumed-
5569 1.1 mrg length assumed-length/assumed-size CHARACTER array. This only
5570 1.1 mrg applies if the actual argument is a "variable"; if it's some
5571 1.1 mrg non-lvalue expression, we are going to evaluate it to a
5572 1.1 mrg temporary below anyway. */
5573 1.1 mrg se.force_no_tmp = 1;
5574 1.1 mrg if ((fsym->attr.contiguous
5575 1.1 mrg || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length
5576 1.1 mrg && (fsym->as->type == AS_ASSUMED_SIZE
5577 1.1 mrg || fsym->as->type == AS_EXPLICIT)))
5578 1.1 mrg && !gfc_is_simply_contiguous (e, false, true)
5579 1.1 mrg && gfc_expr_is_variable (e))
5580 1.1 mrg {
5581 1.1 mrg bool optional = fsym->attr.optional;
5582 1.1 mrg fsym->attr.optional = 0;
5583 1.1 mrg gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent,
5584 1.1 mrg fsym->attr.pointer, fsym,
5585 1.1 mrg fsym->ns->proc_name->name, NULL,
5586 1.1 mrg /* check_contiguous= */ true);
5587 1.1 mrg fsym->attr.optional = optional;
5588 1.1 mrg }
5589 1.1 mrg else
5590 1.1 mrg gfc_conv_expr_descriptor (&se, e);
5591 1.1 mrg gfc = se.expr;
5592 1.1 mrg /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
5593 1.1 mrg elem_len = sizeof(dt) and base_addr = dt(lb) instead.
5594 1.1 mrg gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
5595 1.1 mrg While sm is fine as it uses span*stride and not elem_len. */
5596 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (gfc)))
5597 1.1 mrg gfc = build_fold_indirect_ref_loc (input_location, gfc);
5598 1.1 mrg else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
5599 1.1 mrg gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e);
5600 1.1 mrg }
5601 1.1 mrg if (e->ts.type == BT_CHARACTER)
5602 1.1 mrg {
5603 1.1 mrg if (se.string_length)
5604 1.1 mrg gfc_strlen = se.string_length;
5605 1.1 mrg else if (e->ts.u.cl->backend_decl)
5606 1.1 mrg gfc_strlen = e->ts.u.cl->backend_decl;
5607 1.1 mrg else
5608 1.1 mrg gcc_unreachable ();
5609 1.1 mrg }
5610 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
5611 1.1 mrg
5612 1.1 mrg /* Create array decriptor and set version, rank, attribute, type. */
5613 1.1 mrg cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0
5614 1.1 mrg ? GFC_MAX_DIMENSIONS : e->rank,
5615 1.1 mrg false), "cfi");
5616 1.1 mrg /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
5617 1.1 mrg if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK)
5618 1.1 mrg {
5619 1.1 mrg tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target);
5620 1.1 mrg tmp = build_pointer_type (tmp);
5621 1.1 mrg parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi);
5622 1.1 mrg cfi = build_fold_indirect_ref_loc (input_location, cfi);
5623 1.1 mrg }
5624 1.1 mrg else
5625 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL, cfi);
5626 1.1 mrg
5627 1.1 mrg tmp = gfc_get_cfi_desc_version (cfi);
5628 1.1 mrg gfc_add_modify (&block, tmp,
5629 1.1 mrg build_int_cst (TREE_TYPE (tmp), CFI_VERSION));
5630 1.1 mrg if (e->rank < 0)
5631 1.1 mrg rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc));
5632 1.1 mrg else
5633 1.1 mrg rank = build_int_cst (signed_char_type_node, e->rank);
5634 1.1 mrg tmp = gfc_get_cfi_desc_rank (cfi);
5635 1.1 mrg gfc_add_modify (&block, tmp, rank);
5636 1.1 mrg int itype = CFI_type_other;
5637 1.1 mrg if (e->ts.f90_type == BT_VOID)
5638 1.1 mrg itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5639 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr);
5640 1.1 mrg else
5641 1.1 mrg {
5642 1.1 mrg if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN)
5643 1.1 mrg e->ts = fsym->ts;
5644 1.1 mrg switch (e->ts.type)
5645 1.1 mrg {
5646 1.1 mrg case BT_INTEGER:
5647 1.1 mrg case BT_LOGICAL:
5648 1.1 mrg case BT_REAL:
5649 1.1 mrg case BT_COMPLEX:
5650 1.1 mrg itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind);
5651 1.1 mrg break;
5652 1.1 mrg case BT_CHARACTER:
5653 1.1 mrg itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind);
5654 1.1 mrg break;
5655 1.1 mrg case BT_DERIVED:
5656 1.1 mrg itype = CFI_type_struct;
5657 1.1 mrg break;
5658 1.1 mrg case BT_VOID:
5659 1.1 mrg itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5660 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr);
5661 1.1 mrg break;
5662 1.1 mrg case BT_ASSUMED:
5663 1.1 mrg itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5664 1.1 mrg break;
5665 1.1 mrg case BT_CLASS:
5666 1.1 mrg if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED)
5667 1.1 mrg {
5668 1.1 mrg // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
5669 1.1 mrg // type specifier is assumed-type and is an unlimited polymorphic
5670 1.1 mrg // entity." The actual argument _data component is passed.
5671 1.1 mrg itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5672 1.1 mrg break;
5673 1.1 mrg }
5674 1.1 mrg else
5675 1.1 mrg gcc_unreachable ();
5676 1.1 mrg case BT_PROCEDURE:
5677 1.1 mrg case BT_HOLLERITH:
5678 1.1 mrg case BT_UNION:
5679 1.1 mrg case BT_BOZ:
5680 1.1 mrg case BT_UNKNOWN:
5681 1.1 mrg // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
5682 1.1 mrg gcc_unreachable ();
5683 1.1 mrg }
5684 1.1 mrg }
5685 1.1 mrg
5686 1.1 mrg tmp = gfc_get_cfi_desc_type (cfi);
5687 1.1 mrg gfc_add_modify (&block, tmp,
5688 1.1 mrg build_int_cst (TREE_TYPE (tmp), itype));
5689 1.1 mrg
5690 1.1 mrg int attr = CFI_attribute_other;
5691 1.1 mrg if (fsym->attr.pointer)
5692 1.1 mrg attr = CFI_attribute_pointer;
5693 1.1 mrg else if (fsym->attr.allocatable)
5694 1.1 mrg attr = CFI_attribute_allocatable;
5695 1.1 mrg tmp = gfc_get_cfi_desc_attribute (cfi);
5696 1.1 mrg gfc_add_modify (&block, tmp,
5697 1.1 mrg build_int_cst (TREE_TYPE (tmp), attr));
5698 1.1 mrg
5699 1.1 mrg if (e->rank == 0)
5700 1.1 mrg {
5701 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
5702 1.1 mrg gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc));
5703 1.1 mrg }
5704 1.1 mrg else
5705 1.1 mrg {
5706 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
5707 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (gfc);
5708 1.1 mrg gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
5709 1.1 mrg }
5710 1.1 mrg
5711 1.1 mrg /* Set elem_len if known - must be before the next if block.
5712 1.1 mrg Note that allocatable implies 'len=:'. */
5713 1.1 mrg if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER )
5714 1.1 mrg {
5715 1.1 mrg /* Length is known at compile time; use 'block' for it. */
5716 1.1 mrg tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts));
5717 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5718 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5719 1.1 mrg }
5720 1.1 mrg
5721 1.1 mrg /* When allocatable + intent out, free the cfi descriptor. */
5722 1.1 mrg if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT)
5723 1.1 mrg {
5724 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
5725 1.1 mrg tree call = builtin_decl_explicit (BUILT_IN_FREE);
5726 1.1 mrg call = build_call_expr_loc (input_location, call, 1, tmp);
5727 1.1 mrg gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
5728 1.1 mrg gfc_add_modify (&block, tmp,
5729 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node));
5730 1.1 mrg goto done;
5731 1.1 mrg }
5732 1.1 mrg
5733 1.1 mrg /* If not unallocated/unassociated. */
5734 1.1 mrg gfc_init_block (&block2);
5735 1.1 mrg
5736 1.1 mrg /* Set elem_len, which may be only known at run time. */
5737 1.1 mrg if (e->ts.type == BT_CHARACTER
5738 1.1 mrg && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE))
5739 1.1 mrg {
5740 1.1 mrg gcc_assert (gfc_strlen);
5741 1.1 mrg tmp = gfc_strlen;
5742 1.1 mrg if (e->ts.kind != 1)
5743 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
5744 1.1 mrg gfc_charlen_type_node, tmp,
5745 1.1 mrg build_int_cst (gfc_charlen_type_node,
5746 1.1 mrg e->ts.kind));
5747 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5748 1.1 mrg gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5749 1.1 mrg }
5750 1.1 mrg else if (e->ts.type == BT_ASSUMED)
5751 1.1 mrg {
5752 1.1 mrg tmp = gfc_conv_descriptor_elem_len (gfc);
5753 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5754 1.1 mrg gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5755 1.1 mrg }
5756 1.1 mrg
5757 1.1 mrg if (e->ts.type == BT_ASSUMED)
5758 1.1 mrg {
5759 1.1 mrg /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
5760 1.1 mrg an CFI descriptor. Use the type in the descritor as it provide
5761 1.1 mrg mode information. (Quality of implementation feature.) */
5762 1.1 mrg tree cond;
5763 1.1 mrg tree ctype = gfc_get_cfi_desc_type (cfi);
5764 1.1 mrg tree type = fold_convert (TREE_TYPE (ctype),
5765 1.1 mrg gfc_conv_descriptor_type (gfc));
5766 1.1 mrg tree kind = fold_convert (TREE_TYPE (ctype),
5767 1.1 mrg gfc_conv_descriptor_elem_len (gfc));
5768 1.1 mrg kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
5769 1.1 mrg kind, build_int_cst (TREE_TYPE (type),
5770 1.1 mrg CFI_type_kind_shift));
5771 1.1 mrg
5772 1.1 mrg /* if (BT_VOID) CFI_type_cptr else CFI_type_other */
5773 1.1 mrg /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
5774 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5775 1.1 mrg build_int_cst (TREE_TYPE (type), BT_VOID));
5776 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5777 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_cptr));
5778 1.1 mrg tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5779 1.1 mrg ctype,
5780 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_other));
5781 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5782 1.1 mrg tmp, tmp2);
5783 1.1 mrg /* if (BT_DERIVED) CFI_type_struct else < tmp2 > */
5784 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5785 1.1 mrg build_int_cst (TREE_TYPE (type), BT_DERIVED));
5786 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5787 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_struct));
5788 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5789 1.1 mrg tmp, tmp2);
5790 1.1 mrg /* if (BT_CHARACTER) CFI_type_Character + kind=1 else < tmp2 > */
5791 1.1 mrg /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4. */
5792 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5793 1.1 mrg build_int_cst (TREE_TYPE (type), BT_CHARACTER));
5794 1.1 mrg tmp = build_int_cst (TREE_TYPE (type),
5795 1.1 mrg CFI_type_from_type_kind (CFI_type_Character, 1));
5796 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5797 1.1 mrg ctype, tmp);
5798 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5799 1.1 mrg tmp, tmp2);
5800 1.1 mrg /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else < tmp2 > */
5801 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5802 1.1 mrg build_int_cst (TREE_TYPE (type), BT_COMPLEX));
5803 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type),
5804 1.1 mrg kind, build_int_cst (TREE_TYPE (type), 2));
5805 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp,
5806 1.1 mrg build_int_cst (TREE_TYPE (type),
5807 1.1 mrg CFI_type_Complex));
5808 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5809 1.1 mrg ctype, tmp);
5810 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5811 1.1 mrg tmp, tmp2);
5812 1.1 mrg /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else <tmp2> */
5813 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5814 1.1 mrg build_int_cst (TREE_TYPE (type), BT_INTEGER));
5815 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5816 1.1 mrg build_int_cst (TREE_TYPE (type), BT_LOGICAL));
5817 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5818 1.1 mrg cond, tmp);
5819 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5820 1.1 mrg build_int_cst (TREE_TYPE (type), BT_REAL));
5821 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5822 1.1 mrg cond, tmp);
5823 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type),
5824 1.1 mrg type, kind);
5825 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5826 1.1 mrg ctype, tmp);
5827 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5828 1.1 mrg tmp, tmp2);
5829 1.1 mrg gfc_add_expr_to_block (&block2, tmp2);
5830 1.1 mrg }
5831 1.1 mrg
5832 1.1 mrg if (e->rank != 0)
5833 1.1 mrg {
5834 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */
5835 1.1 mrg tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5836 1.1 mrg /* Loop body. */
5837 1.1 mrg stmtblock_t loop_body;
5838 1.1 mrg gfc_init_block (&loop_body);
5839 1.1 mrg /* cfi->dim[i].lower_bound = (allocatable/pointer)
5840 1.1 mrg ? gfc->dim[i].lbound : 0 */
5841 1.1 mrg if (fsym->attr.pointer || fsym->attr.allocatable)
5842 1.1 mrg tmp = gfc_conv_descriptor_lbound_get (gfc, idx);
5843 1.1 mrg else
5844 1.1 mrg tmp = gfc_index_zero_node;
5845 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp);
5846 1.1 mrg /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
5847 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5848 1.1 mrg gfc_conv_descriptor_ubound_get (gfc, idx),
5849 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx));
5850 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5851 1.1 mrg tmp, gfc_index_one_node);
5852 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
5853 1.1 mrg /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
5854 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5855 1.1 mrg gfc_conv_descriptor_stride_get (gfc, idx),
5856 1.1 mrg gfc_conv_descriptor_span_get (gfc));
5857 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
5858 1.1 mrg
5859 1.1 mrg /* Generate loop. */
5860 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5861 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5862 1.1 mrg gfc_finish_block (&loop_body));
5863 1.1 mrg
5864 1.1 mrg if (e->expr_type == EXPR_VARIABLE
5865 1.1 mrg && e->ref
5866 1.1 mrg && e->ref->u.ar.type == AR_FULL
5867 1.1 mrg && e->symtree->n.sym->attr.dummy
5868 1.1 mrg && e->symtree->n.sym->as
5869 1.1 mrg && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
5870 1.1 mrg {
5871 1.1 mrg tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]),
5872 1.1 mrg gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1));
5873 1.1 mrg }
5874 1.1 mrg }
5875 1.1 mrg
5876 1.1 mrg if (fsym->attr.allocatable || fsym->attr.pointer)
5877 1.1 mrg {
5878 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi),
5879 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5880 1.1 mrg tmp, null_pointer_node);
5881 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5882 1.1 mrg build_empty_stmt (input_location));
5883 1.1 mrg gfc_add_expr_to_block (&block, tmp);
5884 1.1 mrg }
5885 1.1 mrg else
5886 1.1 mrg gfc_add_block_to_block (&block, &block2);
5887 1.1 mrg
5888 1.1 mrg
5889 1.1 mrg done:
5890 1.1 mrg if (present)
5891 1.1 mrg {
5892 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR,
5893 1.1 mrg TREE_TYPE (parmse->expr),
5894 1.1 mrg present, parmse->expr, null_pointer_node);
5895 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5896 1.1 mrg build_empty_stmt (input_location));
5897 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp);
5898 1.1 mrg }
5899 1.1 mrg else
5900 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block);
5901 1.1 mrg
5902 1.1 mrg gfc_init_block (&block);
5903 1.1 mrg
5904 1.1 mrg if ((!fsym->attr.allocatable && !fsym->attr.pointer)
5905 1.1 mrg || fsym->attr.intent == INTENT_IN)
5906 1.1 mrg goto post_call;
5907 1.1 mrg
5908 1.1 mrg gfc_init_block (&block2);
5909 1.1 mrg if (e->rank == 0)
5910 1.1 mrg {
5911 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
5912 1.1 mrg gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
5913 1.1 mrg }
5914 1.1 mrg else
5915 1.1 mrg {
5916 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
5917 1.1 mrg gfc_conv_descriptor_data_set (&block, gfc, tmp);
5918 1.1 mrg
5919 1.1 mrg if (fsym->attr.allocatable)
5920 1.1 mrg {
5921 1.1 mrg /* gfc->span = cfi->elem_len. */
5922 1.1 mrg tmp = fold_convert (gfc_array_index_type,
5923 1.1 mrg gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
5924 1.1 mrg }
5925 1.1 mrg else
5926 1.1 mrg {
5927 1.1 mrg /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
5928 1.1 mrg ? cfi->dim[0].sm : cfi->elem_len). */
5929 1.1 mrg tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
5930 1.1 mrg tmp2 = fold_convert (gfc_array_index_type,
5931 1.1 mrg gfc_get_cfi_desc_elem_len (cfi));
5932 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
5933 1.1 mrg gfc_array_index_type, tmp, tmp2);
5934 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5935 1.1 mrg tmp, gfc_index_zero_node);
5936 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
5937 1.1 mrg gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
5938 1.1 mrg }
5939 1.1 mrg gfc_conv_descriptor_span_set (&block2, gfc, tmp);
5940 1.1 mrg
5941 1.1 mrg /* Calculate offset + set lbound, ubound and stride. */
5942 1.1 mrg gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
5943 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */
5944 1.1 mrg tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5945 1.1 mrg /* Loop body. */
5946 1.1 mrg stmtblock_t loop_body;
5947 1.1 mrg gfc_init_block (&loop_body);
5948 1.1 mrg /* gfc->dim[i].lbound = ... */
5949 1.1 mrg tmp = gfc_get_cfi_dim_lbound (cfi, idx);
5950 1.1 mrg gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
5951 1.1 mrg
5952 1.1 mrg /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
5953 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5954 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx),
5955 1.1 mrg gfc_index_one_node);
5956 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5957 1.1 mrg gfc_get_cfi_dim_extent (cfi, idx), tmp);
5958 1.1 mrg gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
5959 1.1 mrg
5960 1.1 mrg /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
5961 1.1 mrg tmp = gfc_get_cfi_dim_sm (cfi, idx);
5962 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5963 1.1 mrg gfc_array_index_type, tmp,
5964 1.1 mrg fold_convert (gfc_array_index_type,
5965 1.1 mrg gfc_get_cfi_desc_elem_len (cfi)));
5966 1.1 mrg gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
5967 1.1 mrg
5968 1.1 mrg /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
5969 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5970 1.1 mrg gfc_conv_descriptor_stride_get (gfc, idx),
5971 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx));
5972 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5973 1.1 mrg gfc_conv_descriptor_offset_get (gfc), tmp);
5974 1.1 mrg gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
5975 1.1 mrg /* Generate loop. */
5976 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5977 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5978 1.1 mrg gfc_finish_block (&loop_body));
5979 1.1 mrg }
5980 1.1 mrg
5981 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
5982 1.1 mrg {
5983 1.1 mrg tmp = fold_convert (gfc_charlen_type_node,
5984 1.1 mrg gfc_get_cfi_desc_elem_len (cfi));
5985 1.1 mrg if (e->ts.kind != 1)
5986 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5987 1.1 mrg gfc_charlen_type_node, tmp,
5988 1.1 mrg build_int_cst (gfc_charlen_type_node,
5989 1.1 mrg e->ts.kind));
5990 1.1 mrg gfc_add_modify (&block2, gfc_strlen, tmp);
5991 1.1 mrg }
5992 1.1 mrg
5993 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi),
5994 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5995 1.1 mrg tmp, null_pointer_node);
5996 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5997 1.1 mrg build_empty_stmt (input_location));
5998 1.1 mrg gfc_add_expr_to_block (&block, tmp);
5999 1.1 mrg
6000 1.1 mrg post_call:
6001 1.1 mrg gfc_add_block_to_block (&block, &se.post);
6002 1.1 mrg if (present && block.head)
6003 1.1 mrg {
6004 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
6005 1.1 mrg build_empty_stmt (input_location));
6006 1.1 mrg gfc_add_expr_to_block (&parmse->post, tmp);
6007 1.1 mrg }
6008 1.1 mrg else if (block.head)
6009 1.1 mrg gfc_add_block_to_block (&parmse->post, &block);
6010 1.1 mrg }
6011 1.1 mrg
6012 1.1 mrg
6013 1.1 mrg /* Generate code for a procedure call. Note can return se->post != NULL.
6014 1.1 mrg If se->direct_byref is set then se->expr contains the return parameter.
6015 1.1 mrg Return nonzero, if the call has alternate specifiers.
6016 1.1 mrg 'expr' is only needed for procedure pointer components. */
6017 1.1 mrg
6018 1.1 mrg int
6019 1.1 mrg gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
6020 1.1 mrg gfc_actual_arglist * args, gfc_expr * expr,
6021 1.1 mrg vec<tree, va_gc> *append_args)
6022 1.1 mrg {
6023 1.1 mrg gfc_interface_mapping mapping;
6024 1.1 mrg vec<tree, va_gc> *arglist;
6025 1.1 mrg vec<tree, va_gc> *retargs;
6026 1.1 mrg tree tmp;
6027 1.1 mrg tree fntype;
6028 1.1 mrg gfc_se parmse;
6029 1.1 mrg gfc_array_info *info;
6030 1.1 mrg int byref;
6031 1.1 mrg int parm_kind;
6032 1.1 mrg tree type;
6033 1.1 mrg tree var;
6034 1.1 mrg tree len;
6035 1.1 mrg tree base_object;
6036 1.1 mrg vec<tree, va_gc> *stringargs;
6037 1.1 mrg vec<tree, va_gc> *optionalargs;
6038 1.1 mrg tree result = NULL;
6039 1.1 mrg gfc_formal_arglist *formal;
6040 1.1 mrg gfc_actual_arglist *arg;
6041 1.1 mrg int has_alternate_specifier = 0;
6042 1.1 mrg bool need_interface_mapping;
6043 1.1 mrg bool callee_alloc;
6044 1.1 mrg bool ulim_copy;
6045 1.1 mrg gfc_typespec ts;
6046 1.1 mrg gfc_charlen cl;
6047 1.1 mrg gfc_expr *e;
6048 1.1 mrg gfc_symbol *fsym;
6049 1.1 mrg enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
6050 1.1 mrg gfc_component *comp = NULL;
6051 1.1 mrg int arglen;
6052 1.1 mrg unsigned int argc;
6053 1.1 mrg
6054 1.1 mrg arglist = NULL;
6055 1.1 mrg retargs = NULL;
6056 1.1 mrg stringargs = NULL;
6057 1.1 mrg optionalargs = NULL;
6058 1.1 mrg var = NULL_TREE;
6059 1.1 mrg len = NULL_TREE;
6060 1.1 mrg gfc_clear_ts (&ts);
6061 1.1 mrg
6062 1.1 mrg comp = gfc_get_proc_ptr_comp (expr);
6063 1.1 mrg
6064 1.1 mrg bool elemental_proc = (comp
6065 1.1 mrg && comp->ts.interface
6066 1.1 mrg && comp->ts.interface->attr.elemental)
6067 1.1 mrg || (comp && comp->attr.elemental)
6068 1.1 mrg || sym->attr.elemental;
6069 1.1 mrg
6070 1.1 mrg if (se->ss != NULL)
6071 1.1 mrg {
6072 1.1 mrg if (!elemental_proc)
6073 1.1 mrg {
6074 1.1 mrg gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
6075 1.1 mrg if (se->ss->info->useflags)
6076 1.1 mrg {
6077 1.1 mrg gcc_assert ((!comp && gfc_return_by_reference (sym)
6078 1.1 mrg && sym->result->attr.dimension)
6079 1.1 mrg || (comp && comp->attr.dimension)
6080 1.1 mrg || gfc_is_class_array_function (expr));
6081 1.1 mrg gcc_assert (se->loop != NULL);
6082 1.1 mrg /* Access the previously obtained result. */
6083 1.1 mrg gfc_conv_tmp_array_ref (se);
6084 1.1 mrg return 0;
6085 1.1 mrg }
6086 1.1 mrg }
6087 1.1 mrg info = &se->ss->info->data.array;
6088 1.1 mrg }
6089 1.1 mrg else
6090 1.1 mrg info = NULL;
6091 1.1 mrg
6092 1.1 mrg stmtblock_t post, clobbers;
6093 1.1 mrg gfc_init_block (&post);
6094 1.1 mrg gfc_init_block (&clobbers);
6095 1.1 mrg gfc_init_interface_mapping (&mapping);
6096 1.1 mrg if (!comp)
6097 1.1 mrg {
6098 1.1 mrg formal = gfc_sym_get_dummy_args (sym);
6099 1.1 mrg need_interface_mapping = sym->attr.dimension ||
6100 1.1 mrg (sym->ts.type == BT_CHARACTER
6101 1.1 mrg && sym->ts.u.cl->length
6102 1.1 mrg && sym->ts.u.cl->length->expr_type
6103 1.1 mrg != EXPR_CONSTANT);
6104 1.1 mrg }
6105 1.1 mrg else
6106 1.1 mrg {
6107 1.1 mrg formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
6108 1.1 mrg need_interface_mapping = comp->attr.dimension ||
6109 1.1 mrg (comp->ts.type == BT_CHARACTER
6110 1.1 mrg && comp->ts.u.cl->length
6111 1.1 mrg && comp->ts.u.cl->length->expr_type
6112 1.1 mrg != EXPR_CONSTANT);
6113 1.1 mrg }
6114 1.1 mrg
6115 1.1 mrg base_object = NULL_TREE;
6116 1.1 mrg /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
6117 1.1 mrg is the third and fourth argument to such a function call a value
6118 1.1 mrg denoting the number of elements to copy (i.e., most of the time the
6119 1.1 mrg length of a deferred length string). */
6120 1.1 mrg ulim_copy = (formal == NULL)
6121 1.1 mrg && UNLIMITED_POLY (sym)
6122 1.1 mrg && comp && (strcmp ("_copy", comp->name) == 0);
6123 1.1 mrg
6124 1.1 mrg /* Evaluate the arguments. */
6125 1.1 mrg for (arg = args, argc = 0; arg != NULL;
6126 1.1 mrg arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
6127 1.1 mrg {
6128 1.1 mrg bool finalized = false;
6129 1.1 mrg tree derived_array = NULL_TREE;
6130 1.1 mrg
6131 1.1 mrg e = arg->expr;
6132 1.1 mrg fsym = formal ? formal->sym : NULL;
6133 1.1 mrg parm_kind = MISSING;
6134 1.1 mrg
6135 1.1 mrg /* If the procedure requires an explicit interface, the actual
6136 1.1 mrg argument is passed according to the corresponding formal
6137 1.1 mrg argument. If the corresponding formal argument is a POINTER,
6138 1.1 mrg ALLOCATABLE or assumed shape, we do not use g77's calling
6139 1.1 mrg convention, and pass the address of the array descriptor
6140 1.1 mrg instead. Otherwise we use g77's calling convention, in other words
6141 1.1 mrg pass the array data pointer without descriptor. */
6142 1.1 mrg bool nodesc_arg = fsym != NULL
6143 1.1 mrg && !(fsym->attr.pointer || fsym->attr.allocatable)
6144 1.1 mrg && fsym->as
6145 1.1 mrg && fsym->as->type != AS_ASSUMED_SHAPE
6146 1.1 mrg && fsym->as->type != AS_ASSUMED_RANK;
6147 1.1 mrg if (comp)
6148 1.1 mrg nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
6149 1.1 mrg else
6150 1.1 mrg nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
6151 1.1 mrg
6152 1.1 mrg /* Class array expressions are sometimes coming completely unadorned
6153 1.1 mrg with either arrayspec or _data component. Correct that here.
6154 1.1 mrg OOP-TODO: Move this to the frontend. */
6155 1.1 mrg if (e && e->expr_type == EXPR_VARIABLE
6156 1.1 mrg && !e->ref
6157 1.1 mrg && e->ts.type == BT_CLASS
6158 1.1 mrg && (CLASS_DATA (e)->attr.codimension
6159 1.1 mrg || CLASS_DATA (e)->attr.dimension))
6160 1.1 mrg {
6161 1.1 mrg gfc_typespec temp_ts = e->ts;
6162 1.1 mrg gfc_add_class_array_ref (e);
6163 1.1 mrg e->ts = temp_ts;
6164 1.1 mrg }
6165 1.1 mrg
6166 1.1 mrg if (e == NULL)
6167 1.1 mrg {
6168 1.1 mrg if (se->ignore_optional)
6169 1.1 mrg {
6170 1.1 mrg /* Some intrinsics have already been resolved to the correct
6171 1.1 mrg parameters. */
6172 1.1 mrg continue;
6173 1.1 mrg }
6174 1.1 mrg else if (arg->label)
6175 1.1 mrg {
6176 1.1 mrg has_alternate_specifier = 1;
6177 1.1 mrg continue;
6178 1.1 mrg }
6179 1.1 mrg else
6180 1.1 mrg {
6181 1.1 mrg gfc_init_se (&parmse, NULL);
6182 1.1 mrg
6183 1.1 mrg /* For scalar arguments with VALUE attribute which are passed by
6184 1.1 mrg value, pass "0" and a hidden argument gives the optional
6185 1.1 mrg status. */
6186 1.1 mrg if (fsym && fsym->attr.optional && fsym->attr.value
6187 1.1 mrg && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
6188 1.1 mrg && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
6189 1.1 mrg {
6190 1.1 mrg parmse.expr = fold_convert (gfc_sym_type (fsym),
6191 1.1 mrg integer_zero_node);
6192 1.1 mrg vec_safe_push (optionalargs, boolean_false_node);
6193 1.1 mrg }
6194 1.1 mrg else
6195 1.1 mrg {
6196 1.1 mrg /* Pass a NULL pointer for an absent arg. */
6197 1.1 mrg parmse.expr = null_pointer_node;
6198 1.1 mrg
6199 1.1 mrg /* Is it an absent character dummy? */
6200 1.1 mrg bool absent_char = false;
6201 1.1 mrg gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
6202 1.1 mrg
6203 1.1 mrg /* Fall back to inferred type only if no formal. */
6204 1.1 mrg if (fsym)
6205 1.1 mrg absent_char = (fsym->ts.type == BT_CHARACTER);
6206 1.1 mrg else if (dummy_arg)
6207 1.1 mrg absent_char = (gfc_dummy_arg_get_typespec (*dummy_arg).type
6208 1.1 mrg == BT_CHARACTER);
6209 1.1 mrg if (absent_char)
6210 1.1 mrg parmse.string_length = build_int_cst (gfc_charlen_type_node,
6211 1.1 mrg 0);
6212 1.1 mrg }
6213 1.1 mrg }
6214 1.1 mrg }
6215 1.1 mrg else if (arg->expr->expr_type == EXPR_NULL
6216 1.1 mrg && fsym && !fsym->attr.pointer
6217 1.1 mrg && (fsym->ts.type != BT_CLASS
6218 1.1 mrg || !CLASS_DATA (fsym)->attr.class_pointer))
6219 1.1 mrg {
6220 1.1 mrg /* Pass a NULL pointer to denote an absent arg. */
6221 1.1 mrg gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
6222 1.1 mrg && (fsym->ts.type != BT_CLASS
6223 1.1 mrg || !CLASS_DATA (fsym)->attr.allocatable));
6224 1.1 mrg gfc_init_se (&parmse, NULL);
6225 1.1 mrg parmse.expr = null_pointer_node;
6226 1.1 mrg if (fsym->ts.type == BT_CHARACTER)
6227 1.1 mrg parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6228 1.1 mrg }
6229 1.1 mrg else if (fsym && fsym->ts.type == BT_CLASS
6230 1.1 mrg && e->ts.type == BT_DERIVED)
6231 1.1 mrg {
6232 1.1 mrg /* The derived type needs to be converted to a temporary
6233 1.1 mrg CLASS object. */
6234 1.1 mrg gfc_init_se (&parmse, se);
6235 1.1 mrg gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
6236 1.1 mrg fsym->attr.optional
6237 1.1 mrg && e->expr_type == EXPR_VARIABLE
6238 1.1 mrg && e->symtree->n.sym->attr.optional,
6239 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer
6240 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable,
6241 1.1 mrg &derived_array);
6242 1.1 mrg }
6243 1.1 mrg else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
6244 1.1 mrg && e->ts.type != BT_PROCEDURE
6245 1.1 mrg && (gfc_expr_attr (e).flavor != FL_PROCEDURE
6246 1.1 mrg || gfc_expr_attr (e).proc != PROC_UNKNOWN))
6247 1.1 mrg {
6248 1.1 mrg /* The intrinsic type needs to be converted to a temporary
6249 1.1 mrg CLASS object for the unlimited polymorphic formal. */
6250 1.1 mrg gfc_find_vtab (&e->ts);
6251 1.1 mrg gfc_init_se (&parmse, se);
6252 1.1 mrg gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
6253 1.1 mrg
6254 1.1 mrg }
6255 1.1 mrg else if (se->ss && se->ss->info->useflags)
6256 1.1 mrg {
6257 1.1 mrg gfc_ss *ss;
6258 1.1 mrg
6259 1.1 mrg ss = se->ss;
6260 1.1 mrg
6261 1.1 mrg /* An elemental function inside a scalarized loop. */
6262 1.1 mrg gfc_init_se (&parmse, se);
6263 1.1 mrg parm_kind = ELEMENTAL;
6264 1.1 mrg
6265 1.1 mrg /* When no fsym is present, ulim_copy is set and this is a third or
6266 1.1 mrg fourth argument, use call-by-value instead of by reference to
6267 1.1 mrg hand the length properties to the copy routine (i.e., most of the
6268 1.1 mrg time this will be a call to a __copy_character_* routine where the
6269 1.1 mrg third and fourth arguments are the lengths of a deferred length
6270 1.1 mrg char array). */
6271 1.1 mrg if ((fsym && fsym->attr.value)
6272 1.1 mrg || (ulim_copy && (argc == 2 || argc == 3)))
6273 1.1 mrg gfc_conv_expr (&parmse, e);
6274 1.1 mrg else
6275 1.1 mrg gfc_conv_expr_reference (&parmse, e);
6276 1.1 mrg
6277 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->rank
6278 1.1 mrg && e->expr_type == EXPR_FUNCTION)
6279 1.1 mrg parmse.expr = build_fold_indirect_ref_loc (input_location,
6280 1.1 mrg parmse.expr);
6281 1.1 mrg
6282 1.1 mrg if (fsym && fsym->ts.type == BT_DERIVED
6283 1.1 mrg && gfc_is_class_container_ref (e))
6284 1.1 mrg {
6285 1.1 mrg parmse.expr = gfc_class_data_get (parmse.expr);
6286 1.1 mrg
6287 1.1 mrg if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
6288 1.1 mrg && e->symtree->n.sym->attr.optional)
6289 1.1 mrg {
6290 1.1 mrg tree cond = gfc_conv_expr_present (e->symtree->n.sym);
6291 1.1 mrg parmse.expr = build3_loc (input_location, COND_EXPR,
6292 1.1 mrg TREE_TYPE (parmse.expr),
6293 1.1 mrg cond, parmse.expr,
6294 1.1 mrg fold_convert (TREE_TYPE (parmse.expr),
6295 1.1 mrg null_pointer_node));
6296 1.1 mrg }
6297 1.1 mrg }
6298 1.1 mrg
6299 1.1 mrg /* If we are passing an absent array as optional dummy to an
6300 1.1 mrg elemental procedure, make sure that we pass NULL when the data
6301 1.1 mrg pointer is NULL. We need this extra conditional because of
6302 1.1 mrg scalarization which passes arrays elements to the procedure,
6303 1.1 mrg ignoring the fact that the array can be absent/unallocated/... */
6304 1.1 mrg if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
6305 1.1 mrg {
6306 1.1 mrg tree descriptor_data;
6307 1.1 mrg
6308 1.1 mrg descriptor_data = ss->info->data.array.data;
6309 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6310 1.1 mrg descriptor_data,
6311 1.1 mrg fold_convert (TREE_TYPE (descriptor_data),
6312 1.1 mrg null_pointer_node));
6313 1.1 mrg parmse.expr
6314 1.1 mrg = fold_build3_loc (input_location, COND_EXPR,
6315 1.1 mrg TREE_TYPE (parmse.expr),
6316 1.1 mrg gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
6317 1.1 mrg fold_convert (TREE_TYPE (parmse.expr),
6318 1.1 mrg null_pointer_node),
6319 1.1 mrg parmse.expr);
6320 1.1 mrg }
6321 1.1 mrg
6322 1.1 mrg /* The scalarizer does not repackage the reference to a class
6323 1.1 mrg array - instead it returns a pointer to the data element. */
6324 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
6325 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
6326 1.1 mrg fsym->attr.intent != INTENT_IN
6327 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer
6328 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable),
6329 1.1 mrg fsym->attr.optional
6330 1.1 mrg && e->expr_type == EXPR_VARIABLE
6331 1.1 mrg && e->symtree->n.sym->attr.optional,
6332 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer
6333 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable);
6334 1.1 mrg }
6335 1.1 mrg else
6336 1.1 mrg {
6337 1.1 mrg bool scalar;
6338 1.1 mrg gfc_ss *argss;
6339 1.1 mrg
6340 1.1 mrg gfc_init_se (&parmse, NULL);
6341 1.1 mrg
6342 1.1 mrg /* Check whether the expression is a scalar or not; we cannot use
6343 1.1 mrg e->rank as it can be nonzero for functions arguments. */
6344 1.1 mrg argss = gfc_walk_expr (e);
6345 1.1 mrg scalar = argss == gfc_ss_terminator;
6346 1.1 mrg if (!scalar)
6347 1.1 mrg gfc_free_ss_chain (argss);
6348 1.1 mrg
6349 1.1 mrg /* Special handling for passing scalar polymorphic coarrays;
6350 1.1 mrg otherwise one passes "class->_data.data" instead of "&class". */
6351 1.1 mrg if (e->rank == 0 && e->ts.type == BT_CLASS
6352 1.1 mrg && fsym && fsym->ts.type == BT_CLASS
6353 1.1 mrg && CLASS_DATA (fsym)->attr.codimension
6354 1.1 mrg && !CLASS_DATA (fsym)->attr.dimension)
6355 1.1 mrg {
6356 1.1 mrg gfc_add_class_array_ref (e);
6357 1.1 mrg parmse.want_coarray = 1;
6358 1.1 mrg scalar = false;
6359 1.1 mrg }
6360 1.1 mrg
6361 1.1 mrg /* A scalar or transformational function. */
6362 1.1 mrg if (scalar)
6363 1.1 mrg {
6364 1.1 mrg if (e->expr_type == EXPR_VARIABLE
6365 1.1 mrg && e->symtree->n.sym->attr.cray_pointee
6366 1.1 mrg && fsym && fsym->attr.flavor == FL_PROCEDURE)
6367 1.1 mrg {
6368 1.1 mrg /* The Cray pointer needs to be converted to a pointer to
6369 1.1 mrg a type given by the expression. */
6370 1.1 mrg gfc_conv_expr (&parmse, e);
6371 1.1 mrg type = build_pointer_type (TREE_TYPE (parmse.expr));
6372 1.1 mrg tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6373 1.1 mrg parmse.expr = convert (type, tmp);
6374 1.1 mrg }
6375 1.1 mrg
6376 1.1 mrg else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6377 1.1 mrg /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6378 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6379 1.1 mrg
6380 1.1 mrg else if (fsym && fsym->attr.value)
6381 1.1 mrg {
6382 1.1 mrg if (fsym->ts.type == BT_CHARACTER
6383 1.1 mrg && fsym->ts.is_c_interop
6384 1.1 mrg && fsym->ns->proc_name != NULL
6385 1.1 mrg && fsym->ns->proc_name->attr.is_bind_c)
6386 1.1 mrg {
6387 1.1 mrg parmse.expr = NULL;
6388 1.1 mrg conv_scalar_char_value (fsym, &parmse, &e);
6389 1.1 mrg if (parmse.expr == NULL)
6390 1.1 mrg gfc_conv_expr (&parmse, e);
6391 1.1 mrg }
6392 1.1 mrg else
6393 1.1 mrg {
6394 1.1 mrg gfc_conv_expr (&parmse, e);
6395 1.1 mrg if (fsym->attr.optional
6396 1.1 mrg && fsym->ts.type != BT_CLASS
6397 1.1 mrg && fsym->ts.type != BT_DERIVED)
6398 1.1 mrg {
6399 1.1 mrg if (e->expr_type != EXPR_VARIABLE
6400 1.1 mrg || !e->symtree->n.sym->attr.optional
6401 1.1 mrg || e->ref != NULL)
6402 1.1 mrg vec_safe_push (optionalargs, boolean_true_node);
6403 1.1 mrg else
6404 1.1 mrg {
6405 1.1 mrg tmp = gfc_conv_expr_present (e->symtree->n.sym);
6406 1.1 mrg if (!e->symtree->n.sym->attr.value)
6407 1.1 mrg parmse.expr
6408 1.1 mrg = fold_build3_loc (input_location, COND_EXPR,
6409 1.1 mrg TREE_TYPE (parmse.expr),
6410 1.1 mrg tmp, parmse.expr,
6411 1.1 mrg fold_convert (TREE_TYPE (parmse.expr),
6412 1.1 mrg integer_zero_node));
6413 1.1 mrg
6414 1.1 mrg vec_safe_push (optionalargs,
6415 1.1 mrg fold_convert (boolean_type_node,
6416 1.1 mrg tmp));
6417 1.1 mrg }
6418 1.1 mrg }
6419 1.1 mrg }
6420 1.1 mrg }
6421 1.1 mrg
6422 1.1 mrg else if (arg->name && arg->name[0] == '%')
6423 1.1 mrg /* Argument list functions %VAL, %LOC and %REF are signalled
6424 1.1 mrg through arg->name. */
6425 1.1 mrg conv_arglist_function (&parmse, arg->expr, arg->name);
6426 1.1 mrg else if ((e->expr_type == EXPR_FUNCTION)
6427 1.1 mrg && ((e->value.function.esym
6428 1.1 mrg && e->value.function.esym->result->attr.pointer)
6429 1.1 mrg || (!e->value.function.esym
6430 1.1 mrg && e->symtree->n.sym->attr.pointer))
6431 1.1 mrg && fsym && fsym->attr.target)
6432 1.1 mrg /* Make sure the function only gets called once. */
6433 1.1 mrg gfc_conv_expr_reference (&parmse, e);
6434 1.1 mrg else if (e->expr_type == EXPR_FUNCTION
6435 1.1 mrg && e->symtree->n.sym->result
6436 1.1 mrg && e->symtree->n.sym->result != e->symtree->n.sym
6437 1.1 mrg && e->symtree->n.sym->result->attr.proc_pointer)
6438 1.1 mrg {
6439 1.1 mrg /* Functions returning procedure pointers. */
6440 1.1 mrg gfc_conv_expr (&parmse, e);
6441 1.1 mrg if (fsym && fsym->attr.proc_pointer)
6442 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6443 1.1 mrg }
6444 1.1 mrg
6445 1.1 mrg else
6446 1.1 mrg {
6447 1.1 mrg if (e->ts.type == BT_CLASS && fsym
6448 1.1 mrg && fsym->ts.type == BT_CLASS
6449 1.1 mrg && (!CLASS_DATA (fsym)->as
6450 1.1 mrg || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6451 1.1 mrg && CLASS_DATA (e)->attr.codimension)
6452 1.1 mrg {
6453 1.1 mrg gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6454 1.1 mrg gcc_assert (!CLASS_DATA (fsym)->as);
6455 1.1 mrg gfc_add_class_array_ref (e);
6456 1.1 mrg parmse.want_coarray = 1;
6457 1.1 mrg gfc_conv_expr_reference (&parmse, e);
6458 1.1 mrg class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6459 1.1 mrg fsym->attr.optional
6460 1.1 mrg && e->expr_type == EXPR_VARIABLE);
6461 1.1 mrg }
6462 1.1 mrg else if (e->ts.type == BT_CLASS && fsym
6463 1.1 mrg && fsym->ts.type == BT_CLASS
6464 1.1 mrg && !CLASS_DATA (fsym)->as
6465 1.1 mrg && !CLASS_DATA (e)->as
6466 1.1 mrg && strcmp (fsym->ts.u.derived->name,
6467 1.1 mrg e->ts.u.derived->name))
6468 1.1 mrg {
6469 1.1 mrg type = gfc_typenode_for_spec (&fsym->ts);
6470 1.1 mrg var = gfc_create_var (type, fsym->name);
6471 1.1 mrg gfc_conv_expr (&parmse, e);
6472 1.1 mrg if (fsym->attr.optional
6473 1.1 mrg && e->expr_type == EXPR_VARIABLE
6474 1.1 mrg && e->symtree->n.sym->attr.optional)
6475 1.1 mrg {
6476 1.1 mrg stmtblock_t block;
6477 1.1 mrg tree cond;
6478 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6479 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR,
6480 1.1 mrg logical_type_node, tmp,
6481 1.1 mrg fold_convert (TREE_TYPE (tmp),
6482 1.1 mrg null_pointer_node));
6483 1.1 mrg gfc_start_block (&block);
6484 1.1 mrg gfc_add_modify (&block, var,
6485 1.1 mrg fold_build1_loc (input_location,
6486 1.1 mrg VIEW_CONVERT_EXPR,
6487 1.1 mrg type, parmse.expr));
6488 1.1 mrg gfc_add_expr_to_block (&parmse.pre,
6489 1.1 mrg fold_build3_loc (input_location,
6490 1.1 mrg COND_EXPR, void_type_node,
6491 1.1 mrg cond, gfc_finish_block (&block),
6492 1.1 mrg build_empty_stmt (input_location)));
6493 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6494 1.1 mrg parmse.expr = build3_loc (input_location, COND_EXPR,
6495 1.1 mrg TREE_TYPE (parmse.expr),
6496 1.1 mrg cond, parmse.expr,
6497 1.1 mrg fold_convert (TREE_TYPE (parmse.expr),
6498 1.1 mrg null_pointer_node));
6499 1.1 mrg }
6500 1.1 mrg else
6501 1.1 mrg {
6502 1.1 mrg /* Since the internal representation of unlimited
6503 1.1 mrg polymorphic expressions includes an extra field
6504 1.1 mrg that other class objects do not, a cast to the
6505 1.1 mrg formal type does not work. */
6506 1.1 mrg if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6507 1.1 mrg {
6508 1.1 mrg tree efield;
6509 1.1 mrg
6510 1.1 mrg /* Set the _data field. */
6511 1.1 mrg tmp = gfc_class_data_get (var);
6512 1.1 mrg efield = fold_convert (TREE_TYPE (tmp),
6513 1.1 mrg gfc_class_data_get (parmse.expr));
6514 1.1 mrg gfc_add_modify (&parmse.pre, tmp, efield);
6515 1.1 mrg
6516 1.1 mrg /* Set the _vptr field. */
6517 1.1 mrg tmp = gfc_class_vptr_get (var);
6518 1.1 mrg efield = fold_convert (TREE_TYPE (tmp),
6519 1.1 mrg gfc_class_vptr_get (parmse.expr));
6520 1.1 mrg gfc_add_modify (&parmse.pre, tmp, efield);
6521 1.1 mrg
6522 1.1 mrg /* Set the _len field. */
6523 1.1 mrg tmp = gfc_class_len_get (var);
6524 1.1 mrg gfc_add_modify (&parmse.pre, tmp,
6525 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0));
6526 1.1 mrg }
6527 1.1 mrg else
6528 1.1 mrg {
6529 1.1 mrg tmp = fold_build1_loc (input_location,
6530 1.1 mrg VIEW_CONVERT_EXPR,
6531 1.1 mrg type, parmse.expr);
6532 1.1 mrg gfc_add_modify (&parmse.pre, var, tmp);
6533 1.1 mrg ;
6534 1.1 mrg }
6535 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6536 1.1 mrg }
6537 1.1 mrg }
6538 1.1 mrg else
6539 1.1 mrg {
6540 1.1 mrg gfc_conv_expr_reference (&parmse, e);
6541 1.1 mrg
6542 1.1 mrg if (fsym
6543 1.1 mrg && fsym->attr.intent == INTENT_OUT
6544 1.1 mrg && !fsym->attr.allocatable
6545 1.1 mrg && !fsym->attr.pointer
6546 1.1 mrg && e->expr_type == EXPR_VARIABLE
6547 1.1 mrg && e->ref == NULL
6548 1.1 mrg && e->symtree
6549 1.1 mrg && e->symtree->n.sym
6550 1.1 mrg && !e->symtree->n.sym->attr.dimension
6551 1.1 mrg && !e->symtree->n.sym->attr.pointer
6552 1.1 mrg && !e->symtree->n.sym->attr.allocatable
6553 1.1 mrg /* See PR 41453. */
6554 1.1 mrg && !e->symtree->n.sym->attr.dummy
6555 1.1 mrg /* FIXME - PR 87395 and PR 41453 */
6556 1.1 mrg && e->symtree->n.sym->attr.save == SAVE_NONE
6557 1.1 mrg && !e->symtree->n.sym->attr.associate_var
6558 1.1 mrg && e->ts.type != BT_CHARACTER
6559 1.1 mrg && e->ts.type != BT_DERIVED
6560 1.1 mrg && e->ts.type != BT_CLASS
6561 1.1 mrg && !sym->attr.elemental)
6562 1.1 mrg {
6563 1.1 mrg tree var;
6564 1.1 mrg /* FIXME: This fails if var is passed by reference, see PR
6565 1.1 mrg 41453. */
6566 1.1 mrg var = build_fold_indirect_ref_loc (input_location,
6567 1.1 mrg parmse.expr);
6568 1.1 mrg tree clobber = build_clobber (TREE_TYPE (var));
6569 1.1 mrg gfc_add_modify (&clobbers, var, clobber);
6570 1.1 mrg }
6571 1.1 mrg }
6572 1.1 mrg /* Catch base objects that are not variables. */
6573 1.1 mrg if (e->ts.type == BT_CLASS
6574 1.1 mrg && e->expr_type != EXPR_VARIABLE
6575 1.1 mrg && expr && e == expr->base_expr)
6576 1.1 mrg base_object = build_fold_indirect_ref_loc (input_location,
6577 1.1 mrg parmse.expr);
6578 1.1 mrg
6579 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6580 1.1 mrg allocated on entry, it must be deallocated. */
6581 1.1 mrg if (fsym && fsym->attr.intent == INTENT_OUT
6582 1.1 mrg && (fsym->attr.allocatable
6583 1.1 mrg || (fsym->ts.type == BT_CLASS
6584 1.1 mrg && CLASS_DATA (fsym)->attr.allocatable))
6585 1.1 mrg && !is_CFI_desc (fsym, NULL))
6586 1.1 mrg {
6587 1.1 mrg stmtblock_t block;
6588 1.1 mrg tree ptr;
6589 1.1 mrg
6590 1.1 mrg gfc_init_block (&block);
6591 1.1 mrg ptr = parmse.expr;
6592 1.1 mrg if (e->ts.type == BT_CLASS)
6593 1.1 mrg ptr = gfc_class_data_get (ptr);
6594 1.1 mrg
6595 1.1 mrg tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
6596 1.1 mrg NULL_TREE, true,
6597 1.1 mrg e, e->ts);
6598 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6599 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6600 1.1 mrg void_type_node, ptr,
6601 1.1 mrg null_pointer_node);
6602 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6603 1.1 mrg
6604 1.1 mrg if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6605 1.1 mrg {
6606 1.1 mrg gfc_add_modify (&block, ptr,
6607 1.1 mrg fold_convert (TREE_TYPE (ptr),
6608 1.1 mrg null_pointer_node));
6609 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6610 1.1 mrg }
6611 1.1 mrg else if (fsym->ts.type == BT_CLASS)
6612 1.1 mrg {
6613 1.1 mrg gfc_symbol *vtab;
6614 1.1 mrg vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6615 1.1 mrg tmp = gfc_get_symbol_decl (vtab);
6616 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6617 1.1 mrg ptr = gfc_class_vptr_get (parmse.expr);
6618 1.1 mrg gfc_add_modify (&block, ptr,
6619 1.1 mrg fold_convert (TREE_TYPE (ptr), tmp));
6620 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6621 1.1 mrg }
6622 1.1 mrg
6623 1.1 mrg if (fsym->attr.optional
6624 1.1 mrg && e->expr_type == EXPR_VARIABLE
6625 1.1 mrg && e->symtree->n.sym->attr.optional)
6626 1.1 mrg {
6627 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
6628 1.1 mrg void_type_node,
6629 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym),
6630 1.1 mrg gfc_finish_block (&block),
6631 1.1 mrg build_empty_stmt (input_location));
6632 1.1 mrg }
6633 1.1 mrg else
6634 1.1 mrg tmp = gfc_finish_block (&block);
6635 1.1 mrg
6636 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
6637 1.1 mrg }
6638 1.1 mrg
6639 1.1 mrg /* A class array element needs converting back to be a
6640 1.1 mrg class object, if the formal argument is a class object. */
6641 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS
6642 1.1 mrg && e->ts.type == BT_CLASS
6643 1.1 mrg && ((CLASS_DATA (fsym)->as
6644 1.1 mrg && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6645 1.1 mrg || CLASS_DATA (e)->attr.dimension))
6646 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6647 1.1 mrg fsym->attr.intent != INTENT_IN
6648 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer
6649 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable),
6650 1.1 mrg fsym->attr.optional
6651 1.1 mrg && e->expr_type == EXPR_VARIABLE
6652 1.1 mrg && e->symtree->n.sym->attr.optional,
6653 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer
6654 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable);
6655 1.1 mrg
6656 1.1 mrg if (fsym && (fsym->ts.type == BT_DERIVED
6657 1.1 mrg || fsym->ts.type == BT_ASSUMED)
6658 1.1 mrg && e->ts.type == BT_CLASS
6659 1.1 mrg && !CLASS_DATA (e)->attr.dimension
6660 1.1 mrg && !CLASS_DATA (e)->attr.codimension)
6661 1.1 mrg {
6662 1.1 mrg parmse.expr = gfc_class_data_get (parmse.expr);
6663 1.1 mrg /* The result is a class temporary, whose _data component
6664 1.1 mrg must be freed to avoid a memory leak. */
6665 1.1 mrg if (e->expr_type == EXPR_FUNCTION
6666 1.1 mrg && CLASS_DATA (e)->attr.allocatable)
6667 1.1 mrg {
6668 1.1 mrg tree zero;
6669 1.1 mrg
6670 1.1 mrg gfc_expr *var;
6671 1.1 mrg
6672 1.1 mrg /* Borrow the function symbol to make a call to
6673 1.1 mrg gfc_add_finalizer_call and then restore it. */
6674 1.1 mrg tmp = e->symtree->n.sym->backend_decl;
6675 1.1 mrg e->symtree->n.sym->backend_decl
6676 1.1 mrg = TREE_OPERAND (parmse.expr, 0);
6677 1.1 mrg e->symtree->n.sym->attr.flavor = FL_VARIABLE;
6678 1.1 mrg var = gfc_lval_expr_from_sym (e->symtree->n.sym);
6679 1.1 mrg finalized = gfc_add_finalizer_call (&parmse.post,
6680 1.1 mrg var);
6681 1.1 mrg gfc_free_expr (var);
6682 1.1 mrg e->symtree->n.sym->backend_decl = tmp;
6683 1.1 mrg e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
6684 1.1 mrg
6685 1.1 mrg /* Then free the class _data. */
6686 1.1 mrg zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6687 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
6688 1.1 mrg logical_type_node,
6689 1.1 mrg parmse.expr, zero);
6690 1.1 mrg tmp = build3_v (COND_EXPR, tmp,
6691 1.1 mrg gfc_call_free (parmse.expr),
6692 1.1 mrg build_empty_stmt (input_location));
6693 1.1 mrg gfc_add_expr_to_block (&parmse.post, tmp);
6694 1.1 mrg gfc_add_modify (&parmse.post, parmse.expr, zero);
6695 1.1 mrg }
6696 1.1 mrg }
6697 1.1 mrg
6698 1.1 mrg /* Wrap scalar variable in a descriptor. We need to convert
6699 1.1 mrg the address of a pointer back to the pointer itself before,
6700 1.1 mrg we can assign it to the data field. */
6701 1.1 mrg
6702 1.1 mrg if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6703 1.1 mrg && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6704 1.1 mrg {
6705 1.1 mrg tmp = parmse.expr;
6706 1.1 mrg if (TREE_CODE (tmp) == ADDR_EXPR)
6707 1.1 mrg tmp = TREE_OPERAND (tmp, 0);
6708 1.1 mrg parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6709 1.1 mrg fsym->attr);
6710 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE,
6711 1.1 mrg parmse.expr);
6712 1.1 mrg }
6713 1.1 mrg else if (fsym && e->expr_type != EXPR_NULL
6714 1.1 mrg && ((fsym->attr.pointer
6715 1.1 mrg && fsym->attr.flavor != FL_PROCEDURE)
6716 1.1 mrg || (fsym->attr.proc_pointer
6717 1.1 mrg && !(e->expr_type == EXPR_VARIABLE
6718 1.1 mrg && e->symtree->n.sym->attr.dummy))
6719 1.1 mrg || (fsym->attr.proc_pointer
6720 1.1 mrg && e->expr_type == EXPR_VARIABLE
6721 1.1 mrg && gfc_is_proc_ptr_comp (e))
6722 1.1 mrg || (fsym->attr.allocatable
6723 1.1 mrg && fsym->attr.flavor != FL_PROCEDURE)))
6724 1.1 mrg {
6725 1.1 mrg /* Scalar pointer dummy args require an extra level of
6726 1.1 mrg indirection. The null pointer already contains
6727 1.1 mrg this level of indirection. */
6728 1.1 mrg parm_kind = SCALAR_POINTER;
6729 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6730 1.1 mrg }
6731 1.1 mrg }
6732 1.1 mrg }
6733 1.1 mrg else if (e->ts.type == BT_CLASS
6734 1.1 mrg && fsym && fsym->ts.type == BT_CLASS
6735 1.1 mrg && (CLASS_DATA (fsym)->attr.dimension
6736 1.1 mrg || CLASS_DATA (fsym)->attr.codimension))
6737 1.1 mrg {
6738 1.1 mrg /* Pass a class array. */
6739 1.1 mrg parmse.use_offset = 1;
6740 1.1 mrg gfc_conv_expr_descriptor (&parmse, e);
6741 1.1 mrg
6742 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6743 1.1 mrg allocated on entry, it must be deallocated. */
6744 1.1 mrg if (fsym->attr.intent == INTENT_OUT
6745 1.1 mrg && CLASS_DATA (fsym)->attr.allocatable)
6746 1.1 mrg {
6747 1.1 mrg stmtblock_t block;
6748 1.1 mrg tree ptr;
6749 1.1 mrg
6750 1.1 mrg gfc_init_block (&block);
6751 1.1 mrg ptr = parmse.expr;
6752 1.1 mrg ptr = gfc_class_data_get (ptr);
6753 1.1 mrg
6754 1.1 mrg tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6755 1.1 mrg NULL_TREE, NULL_TREE,
6756 1.1 mrg NULL_TREE, true, e,
6757 1.1 mrg GFC_CAF_COARRAY_NOCOARRAY);
6758 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6759 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6760 1.1 mrg void_type_node, ptr,
6761 1.1 mrg null_pointer_node);
6762 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6763 1.1 mrg gfc_reset_vptr (&block, e);
6764 1.1 mrg
6765 1.1 mrg if (fsym->attr.optional
6766 1.1 mrg && e->expr_type == EXPR_VARIABLE
6767 1.1 mrg && (!e->ref
6768 1.1 mrg || (e->ref->type == REF_ARRAY
6769 1.1 mrg && e->ref->u.ar.type != AR_FULL))
6770 1.1 mrg && e->symtree->n.sym->attr.optional)
6771 1.1 mrg {
6772 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
6773 1.1 mrg void_type_node,
6774 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym),
6775 1.1 mrg gfc_finish_block (&block),
6776 1.1 mrg build_empty_stmt (input_location));
6777 1.1 mrg }
6778 1.1 mrg else
6779 1.1 mrg tmp = gfc_finish_block (&block);
6780 1.1 mrg
6781 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
6782 1.1 mrg }
6783 1.1 mrg
6784 1.1 mrg /* The conversion does not repackage the reference to a class
6785 1.1 mrg array - _data descriptor. */
6786 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6787 1.1 mrg fsym->attr.intent != INTENT_IN
6788 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer
6789 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable),
6790 1.1 mrg fsym->attr.optional
6791 1.1 mrg && e->expr_type == EXPR_VARIABLE
6792 1.1 mrg && e->symtree->n.sym->attr.optional,
6793 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer
6794 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable);
6795 1.1 mrg }
6796 1.1 mrg else
6797 1.1 mrg {
6798 1.1 mrg /* If the argument is a function call that may not create
6799 1.1 mrg a temporary for the result, we have to check that we
6800 1.1 mrg can do it, i.e. that there is no alias between this
6801 1.1 mrg argument and another one. */
6802 1.1 mrg if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6803 1.1 mrg {
6804 1.1 mrg gfc_expr *iarg;
6805 1.1 mrg sym_intent intent;
6806 1.1 mrg
6807 1.1 mrg if (fsym != NULL)
6808 1.1 mrg intent = fsym->attr.intent;
6809 1.1 mrg else
6810 1.1 mrg intent = INTENT_UNKNOWN;
6811 1.1 mrg
6812 1.1 mrg if (gfc_check_fncall_dependency (e, intent, sym, args,
6813 1.1 mrg NOT_ELEMENTAL))
6814 1.1 mrg parmse.force_tmp = 1;
6815 1.1 mrg
6816 1.1 mrg iarg = e->value.function.actual->expr;
6817 1.1 mrg
6818 1.1 mrg /* Temporary needed if aliasing due to host association. */
6819 1.1 mrg if (sym->attr.contained
6820 1.1 mrg && !sym->attr.pure
6821 1.1 mrg && !sym->attr.implicit_pure
6822 1.1 mrg && !sym->attr.use_assoc
6823 1.1 mrg && iarg->expr_type == EXPR_VARIABLE
6824 1.1 mrg && sym->ns == iarg->symtree->n.sym->ns)
6825 1.1 mrg parmse.force_tmp = 1;
6826 1.1 mrg
6827 1.1 mrg /* Ditto within module. */
6828 1.1 mrg if (sym->attr.use_assoc
6829 1.1 mrg && !sym->attr.pure
6830 1.1 mrg && !sym->attr.implicit_pure
6831 1.1 mrg && iarg->expr_type == EXPR_VARIABLE
6832 1.1 mrg && sym->module == iarg->symtree->n.sym->module)
6833 1.1 mrg parmse.force_tmp = 1;
6834 1.1 mrg }
6835 1.1 mrg
6836 1.1 mrg /* Special case for assumed-rank arrays: when passing an
6837 1.1 mrg argument to a nonallocatable/nonpointer dummy, the bounds have
6838 1.1 mrg to be reset as otherwise a last-dim ubound of -1 is
6839 1.1 mrg indistinguishable from an assumed-size array in the callee. */
6840 1.1 mrg if (!sym->attr.is_bind_c && e && fsym && fsym->as
6841 1.1 mrg && fsym->as->type == AS_ASSUMED_RANK
6842 1.1 mrg && e->rank != -1
6843 1.1 mrg && e->expr_type == EXPR_VARIABLE
6844 1.1 mrg && ((fsym->ts.type == BT_CLASS
6845 1.1 mrg && !CLASS_DATA (fsym)->attr.class_pointer
6846 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable)
6847 1.1 mrg || (fsym->ts.type != BT_CLASS
6848 1.1 mrg && !fsym->attr.pointer && !fsym->attr.allocatable)))
6849 1.1 mrg {
6850 1.1 mrg /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
6851 1.1 mrg gfc_ref *ref;
6852 1.1 mrg for (ref = e->ref; ref->next; ref = ref->next)
6853 1.1 mrg ;
6854 1.1 mrg if (ref->u.ar.type == AR_FULL
6855 1.1 mrg && ref->u.ar.as->type != AS_ASSUMED_SIZE)
6856 1.1 mrg ref->u.ar.type = AR_SECTION;
6857 1.1 mrg }
6858 1.1 mrg
6859 1.1 mrg if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6860 1.1 mrg /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6861 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6862 1.1 mrg
6863 1.1 mrg else if (e->expr_type == EXPR_VARIABLE
6864 1.1 mrg && is_subref_array (e)
6865 1.1 mrg && !(fsym && fsym->attr.pointer))
6866 1.1 mrg /* The actual argument is a component reference to an
6867 1.1 mrg array of derived types. In this case, the argument
6868 1.1 mrg is converted to a temporary, which is passed and then
6869 1.1 mrg written back after the procedure call. */
6870 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6871 1.1 mrg fsym ? fsym->attr.intent : INTENT_INOUT,
6872 1.1 mrg fsym && fsym->attr.pointer);
6873 1.1 mrg
6874 1.1 mrg else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
6875 1.1 mrg && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
6876 1.1 mrg && nodesc_arg && fsym->ts.type == BT_DERIVED)
6877 1.1 mrg /* An assumed size class actual argument being passed to
6878 1.1 mrg a 'no descriptor' formal argument just requires the
6879 1.1 mrg data pointer to be passed. For class dummy arguments
6880 1.1 mrg this is stored in the symbol backend decl.. */
6881 1.1 mrg parmse.expr = e->symtree->n.sym->backend_decl;
6882 1.1 mrg
6883 1.1 mrg else if (gfc_is_class_array_ref (e, NULL)
6884 1.1 mrg && fsym && fsym->ts.type == BT_DERIVED)
6885 1.1 mrg /* The actual argument is a component reference to an
6886 1.1 mrg array of derived types. In this case, the argument
6887 1.1 mrg is converted to a temporary, which is passed and then
6888 1.1 mrg written back after the procedure call.
6889 1.1 mrg OOP-TODO: Insert code so that if the dynamic type is
6890 1.1 mrg the same as the declared type, copy-in/copy-out does
6891 1.1 mrg not occur. */
6892 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6893 1.1 mrg fsym->attr.intent,
6894 1.1 mrg fsym->attr.pointer);
6895 1.1 mrg
6896 1.1 mrg else if (gfc_is_class_array_function (e)
6897 1.1 mrg && fsym && fsym->ts.type == BT_DERIVED)
6898 1.1 mrg /* See previous comment. For function actual argument,
6899 1.1 mrg the write out is not needed so the intent is set as
6900 1.1 mrg intent in. */
6901 1.1 mrg {
6902 1.1 mrg e->must_finalize = 1;
6903 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6904 1.1 mrg INTENT_IN, fsym->attr.pointer);
6905 1.1 mrg }
6906 1.1 mrg else if (fsym && fsym->attr.contiguous
6907 1.1 mrg && !gfc_is_simply_contiguous (e, false, true)
6908 1.1 mrg && gfc_expr_is_variable (e))
6909 1.1 mrg {
6910 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6911 1.1 mrg fsym->attr.intent,
6912 1.1 mrg fsym->attr.pointer);
6913 1.1 mrg }
6914 1.1 mrg else
6915 1.1 mrg /* This is where we introduce a temporary to store the
6916 1.1 mrg result of a non-lvalue array expression. */
6917 1.1 mrg gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6918 1.1 mrg sym->name, NULL);
6919 1.1 mrg
6920 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6921 1.1 mrg allocated on entry, it must be deallocated.
6922 1.1 mrg CFI descriptors are handled elsewhere. */
6923 1.1 mrg if (fsym && fsym->attr.allocatable
6924 1.1 mrg && fsym->attr.intent == INTENT_OUT
6925 1.1 mrg && !is_CFI_desc (fsym, NULL))
6926 1.1 mrg {
6927 1.1 mrg if (fsym->ts.type == BT_DERIVED
6928 1.1 mrg && fsym->ts.u.derived->attr.alloc_comp)
6929 1.1 mrg {
6930 1.1 mrg // deallocate the components first
6931 1.1 mrg tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6932 1.1 mrg parmse.expr, e->rank);
6933 1.1 mrg /* But check whether dummy argument is optional. */
6934 1.1 mrg if (tmp != NULL_TREE
6935 1.1 mrg && fsym->attr.optional
6936 1.1 mrg && e->expr_type == EXPR_VARIABLE
6937 1.1 mrg && e->symtree->n.sym->attr.optional)
6938 1.1 mrg {
6939 1.1 mrg tree present;
6940 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym);
6941 1.1 mrg tmp = build3_v (COND_EXPR, present, tmp,
6942 1.1 mrg build_empty_stmt (input_location));
6943 1.1 mrg }
6944 1.1 mrg if (tmp != NULL_TREE)
6945 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
6946 1.1 mrg }
6947 1.1 mrg
6948 1.1 mrg tmp = parmse.expr;
6949 1.1 mrg /* With bind(C), the actual argument is replaced by a bind-C
6950 1.1 mrg descriptor; in this case, the data component arrives here,
6951 1.1 mrg which shall not be dereferenced, but still freed and
6952 1.1 mrg nullified. */
6953 1.1 mrg if (TREE_TYPE(tmp) != pvoid_type_node)
6954 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
6955 1.1 mrg parmse.expr);
6956 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6957 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp);
6958 1.1 mrg tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6959 1.1 mrg NULL_TREE, NULL_TREE, true,
6960 1.1 mrg e,
6961 1.1 mrg GFC_CAF_COARRAY_NOCOARRAY);
6962 1.1 mrg if (fsym->attr.optional
6963 1.1 mrg && e->expr_type == EXPR_VARIABLE
6964 1.1 mrg && e->symtree->n.sym->attr.optional)
6965 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
6966 1.1 mrg void_type_node,
6967 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym),
6968 1.1 mrg tmp, build_empty_stmt (input_location));
6969 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
6970 1.1 mrg }
6971 1.1 mrg }
6972 1.1 mrg }
6973 1.1 mrg /* Special case for an assumed-rank dummy argument. */
6974 1.1 mrg if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
6975 1.1 mrg && (fsym->ts.type == BT_CLASS
6976 1.1 mrg ? (CLASS_DATA (fsym)->as
6977 1.1 mrg && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6978 1.1 mrg : (fsym->as && fsym->as->type == AS_ASSUMED_RANK)))
6979 1.1 mrg {
6980 1.1 mrg if (fsym->ts.type == BT_CLASS
6981 1.1 mrg ? (CLASS_DATA (fsym)->attr.class_pointer
6982 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable)
6983 1.1 mrg : (fsym->attr.pointer || fsym->attr.allocatable))
6984 1.1 mrg {
6985 1.1 mrg /* Unallocated allocatable arrays and unassociated pointer
6986 1.1 mrg arrays need their dtype setting if they are argument
6987 1.1 mrg associated with assumed rank dummies to set the rank. */
6988 1.1 mrg set_dtype_for_unallocated (&parmse, e);
6989 1.1 mrg }
6990 1.1 mrg else if (e->expr_type == EXPR_VARIABLE
6991 1.1 mrg && e->symtree->n.sym->attr.dummy
6992 1.1 mrg && (e->ts.type == BT_CLASS
6993 1.1 mrg ? (e->ref && e->ref->next
6994 1.1 mrg && e->ref->next->type == REF_ARRAY
6995 1.1 mrg && e->ref->next->u.ar.type == AR_FULL
6996 1.1 mrg && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
6997 1.1 mrg : (e->ref && e->ref->type == REF_ARRAY
6998 1.1 mrg && e->ref->u.ar.type == AR_FULL
6999 1.1 mrg && e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
7000 1.1 mrg {
7001 1.1 mrg /* Assumed-size actual to assumed-rank dummy requires
7002 1.1 mrg dim[rank-1].ubound = -1. */
7003 1.1 mrg tree minus_one;
7004 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
7005 1.1 mrg if (fsym->ts.type == BT_CLASS)
7006 1.1 mrg tmp = gfc_class_data_get (tmp);
7007 1.1 mrg minus_one = build_int_cst (gfc_array_index_type, -1);
7008 1.1 mrg gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
7009 1.1 mrg gfc_rank_cst[e->rank - 1],
7010 1.1 mrg minus_one);
7011 1.1 mrg }
7012 1.1 mrg }
7013 1.1 mrg
7014 1.1 mrg /* The case with fsym->attr.optional is that of a user subroutine
7015 1.1 mrg with an interface indicating an optional argument. When we call
7016 1.1 mrg an intrinsic subroutine, however, fsym is NULL, but we might still
7017 1.1 mrg have an optional argument, so we proceed to the substitution
7018 1.1 mrg just in case. */
7019 1.1 mrg if (e && (fsym == NULL || fsym->attr.optional))
7020 1.1 mrg {
7021 1.1 mrg /* If an optional argument is itself an optional dummy argument,
7022 1.1 mrg check its presence and substitute a null if absent. This is
7023 1.1 mrg only needed when passing an array to an elemental procedure
7024 1.1 mrg as then array elements are accessed - or no NULL pointer is
7025 1.1 mrg allowed and a "1" or "0" should be passed if not present.
7026 1.1 mrg When passing a non-array-descriptor full array to a
7027 1.1 mrg non-array-descriptor dummy, no check is needed. For
7028 1.1 mrg array-descriptor actual to array-descriptor dummy, see
7029 1.1 mrg PR 41911 for why a check has to be inserted.
7030 1.1 mrg fsym == NULL is checked as intrinsics required the descriptor
7031 1.1 mrg but do not always set fsym.
7032 1.1 mrg Also, it is necessary to pass a NULL pointer to library routines
7033 1.1 mrg which usually ignore optional arguments, so they can handle
7034 1.1 mrg these themselves. */
7035 1.1 mrg if (e->expr_type == EXPR_VARIABLE
7036 1.1 mrg && e->symtree->n.sym->attr.optional
7037 1.1 mrg && (((e->rank != 0 && elemental_proc)
7038 1.1 mrg || e->representation.length || e->ts.type == BT_CHARACTER
7039 1.1 mrg || (e->rank != 0
7040 1.1 mrg && (fsym == NULL
7041 1.1 mrg || (fsym->as
7042 1.1 mrg && (fsym->as->type == AS_ASSUMED_SHAPE
7043 1.1 mrg || fsym->as->type == AS_ASSUMED_RANK
7044 1.1 mrg || fsym->as->type == AS_DEFERRED)))))
7045 1.1 mrg || se->ignore_optional))
7046 1.1 mrg gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
7047 1.1 mrg e->representation.length);
7048 1.1 mrg }
7049 1.1 mrg
7050 1.1 mrg if (fsym && e)
7051 1.1 mrg {
7052 1.1 mrg /* Obtain the character length of an assumed character length
7053 1.1 mrg length procedure from the typespec. */
7054 1.1 mrg if (fsym->ts.type == BT_CHARACTER
7055 1.1 mrg && parmse.string_length == NULL_TREE
7056 1.1 mrg && e->ts.type == BT_PROCEDURE
7057 1.1 mrg && e->symtree->n.sym->ts.type == BT_CHARACTER
7058 1.1 mrg && e->symtree->n.sym->ts.u.cl->length != NULL
7059 1.1 mrg && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
7060 1.1 mrg {
7061 1.1 mrg gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
7062 1.1 mrg parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
7063 1.1 mrg }
7064 1.1 mrg }
7065 1.1 mrg
7066 1.1 mrg if (fsym && need_interface_mapping && e)
7067 1.1 mrg gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
7068 1.1 mrg
7069 1.1 mrg gfc_add_block_to_block (&se->pre, &parmse.pre);
7070 1.1 mrg gfc_add_block_to_block (&post, &parmse.post);
7071 1.1 mrg
7072 1.1 mrg /* Allocated allocatable components of derived types must be
7073 1.1 mrg deallocated for non-variable scalars, array arguments to elemental
7074 1.1 mrg procedures, and array arguments with descriptor to non-elemental
7075 1.1 mrg procedures. As bounds information for descriptorless arrays is no
7076 1.1 mrg longer available here, they are dealt with in trans-array.cc
7077 1.1 mrg (gfc_conv_array_parameter). */
7078 1.1 mrg if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
7079 1.1 mrg && e->ts.u.derived->attr.alloc_comp
7080 1.1 mrg && (e->rank == 0 || elemental_proc || !nodesc_arg)
7081 1.1 mrg && !expr_may_alias_variables (e, elemental_proc))
7082 1.1 mrg {
7083 1.1 mrg int parm_rank;
7084 1.1 mrg /* It is known the e returns a structure type with at least one
7085 1.1 mrg allocatable component. When e is a function, ensure that the
7086 1.1 mrg function is called once only by using a temporary variable. */
7087 1.1 mrg if (!DECL_P (parmse.expr))
7088 1.1 mrg parmse.expr = gfc_evaluate_now_loc (input_location,
7089 1.1 mrg parmse.expr, &se->pre);
7090 1.1 mrg
7091 1.1 mrg if (fsym && fsym->attr.value)
7092 1.1 mrg tmp = parmse.expr;
7093 1.1 mrg else
7094 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
7095 1.1 mrg parmse.expr);
7096 1.1 mrg
7097 1.1 mrg parm_rank = e->rank;
7098 1.1 mrg switch (parm_kind)
7099 1.1 mrg {
7100 1.1 mrg case (ELEMENTAL):
7101 1.1 mrg case (SCALAR):
7102 1.1 mrg parm_rank = 0;
7103 1.1 mrg break;
7104 1.1 mrg
7105 1.1 mrg case (SCALAR_POINTER):
7106 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location,
7107 1.1 mrg tmp);
7108 1.1 mrg break;
7109 1.1 mrg }
7110 1.1 mrg
7111 1.1 mrg if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
7112 1.1 mrg {
7113 1.1 mrg /* The derived type is passed to gfc_deallocate_alloc_comp.
7114 1.1 mrg Therefore, class actuals can be handled correctly but derived
7115 1.1 mrg types passed to class formals need the _data component. */
7116 1.1 mrg tmp = gfc_class_data_get (tmp);
7117 1.1 mrg if (!CLASS_DATA (fsym)->attr.dimension)
7118 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
7119 1.1 mrg }
7120 1.1 mrg
7121 1.1 mrg if (e->expr_type == EXPR_OP
7122 1.1 mrg && e->value.op.op == INTRINSIC_PARENTHESES
7123 1.1 mrg && e->value.op.op1->expr_type == EXPR_VARIABLE)
7124 1.1 mrg {
7125 1.1 mrg tree local_tmp;
7126 1.1 mrg local_tmp = gfc_evaluate_now (tmp, &se->pre);
7127 1.1 mrg local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
7128 1.1 mrg parm_rank, 0);
7129 1.1 mrg gfc_add_expr_to_block (&se->post, local_tmp);
7130 1.1 mrg }
7131 1.1 mrg
7132 1.1 mrg if (!finalized && !e->must_finalize)
7133 1.1 mrg {
7134 1.1 mrg bool scalar_res_outside_loop;
7135 1.1 mrg scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
7136 1.1 mrg && parm_rank == 0
7137 1.1 mrg && parmse.loop;
7138 1.1 mrg
7139 1.1 mrg /* Scalars passed to an assumed rank argument are converted to
7140 1.1 mrg a descriptor. Obtain the data field before deallocating any
7141 1.1 mrg allocatable components. */
7142 1.1 mrg if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7143 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp);
7144 1.1 mrg
7145 1.1 mrg if (scalar_res_outside_loop)
7146 1.1 mrg {
7147 1.1 mrg /* Go through the ss chain to find the argument and use
7148 1.1 mrg the stored value. */
7149 1.1 mrg gfc_ss *tmp_ss = parmse.loop->ss;
7150 1.1 mrg for (; tmp_ss; tmp_ss = tmp_ss->next)
7151 1.1 mrg if (tmp_ss->info
7152 1.1 mrg && tmp_ss->info->expr == e
7153 1.1 mrg && tmp_ss->info->data.scalar.value != NULL_TREE)
7154 1.1 mrg {
7155 1.1 mrg tmp = tmp_ss->info->data.scalar.value;
7156 1.1 mrg break;
7157 1.1 mrg }
7158 1.1 mrg }
7159 1.1 mrg
7160 1.1 mrg STRIP_NOPS (tmp);
7161 1.1 mrg
7162 1.1 mrg if (derived_array != NULL_TREE)
7163 1.1 mrg tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
7164 1.1 mrg derived_array,
7165 1.1 mrg parm_rank);
7166 1.1 mrg else if ((e->ts.type == BT_CLASS
7167 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
7168 1.1 mrg || e->ts.type == BT_DERIVED)
7169 1.1 mrg tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
7170 1.1 mrg parm_rank);
7171 1.1 mrg else if (e->ts.type == BT_CLASS)
7172 1.1 mrg tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
7173 1.1 mrg tmp, parm_rank);
7174 1.1 mrg
7175 1.1 mrg if (scalar_res_outside_loop)
7176 1.1 mrg gfc_add_expr_to_block (&parmse.loop->post, tmp);
7177 1.1 mrg else
7178 1.1 mrg gfc_prepend_expr_to_block (&post, tmp);
7179 1.1 mrg }
7180 1.1 mrg }
7181 1.1 mrg
7182 1.1 mrg /* Add argument checking of passing an unallocated/NULL actual to
7183 1.1 mrg a nonallocatable/nonpointer dummy. */
7184 1.1 mrg
7185 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
7186 1.1 mrg {
7187 1.1 mrg symbol_attribute attr;
7188 1.1 mrg char *msg;
7189 1.1 mrg tree cond;
7190 1.1 mrg tree tmp;
7191 1.1 mrg symbol_attribute fsym_attr;
7192 1.1 mrg
7193 1.1 mrg if (fsym)
7194 1.1 mrg {
7195 1.1 mrg if (fsym->ts.type == BT_CLASS)
7196 1.1 mrg {
7197 1.1 mrg fsym_attr = CLASS_DATA (fsym)->attr;
7198 1.1 mrg fsym_attr.pointer = fsym_attr.class_pointer;
7199 1.1 mrg }
7200 1.1 mrg else
7201 1.1 mrg fsym_attr = fsym->attr;
7202 1.1 mrg }
7203 1.1 mrg
7204 1.1 mrg if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
7205 1.1 mrg attr = gfc_expr_attr (e);
7206 1.1 mrg else
7207 1.1 mrg goto end_pointer_check;
7208 1.1 mrg
7209 1.1 mrg /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
7210 1.1 mrg allocatable to an optional dummy, cf. 12.5.2.12. */
7211 1.1 mrg if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
7212 1.1 mrg && (gfc_option.allow_std & GFC_STD_F2008) != 0)
7213 1.1 mrg goto end_pointer_check;
7214 1.1 mrg
7215 1.1 mrg if (attr.optional)
7216 1.1 mrg {
7217 1.1 mrg /* If the actual argument is an optional pointer/allocatable and
7218 1.1 mrg the formal argument takes an nonpointer optional value,
7219 1.1 mrg it is invalid to pass a non-present argument on, even
7220 1.1 mrg though there is no technical reason for this in gfortran.
7221 1.1 mrg See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
7222 1.1 mrg tree present, null_ptr, type;
7223 1.1 mrg
7224 1.1 mrg if (attr.allocatable
7225 1.1 mrg && (fsym == NULL || !fsym_attr.allocatable))
7226 1.1 mrg msg = xasprintf ("Allocatable actual argument '%s' is not "
7227 1.1 mrg "allocated or not present",
7228 1.1 mrg e->symtree->n.sym->name);
7229 1.1 mrg else if (attr.pointer
7230 1.1 mrg && (fsym == NULL || !fsym_attr.pointer))
7231 1.1 mrg msg = xasprintf ("Pointer actual argument '%s' is not "
7232 1.1 mrg "associated or not present",
7233 1.1 mrg e->symtree->n.sym->name);
7234 1.1 mrg else if (attr.proc_pointer && !e->value.function.actual
7235 1.1 mrg && (fsym == NULL || !fsym_attr.proc_pointer))
7236 1.1 mrg msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7237 1.1 mrg "associated or not present",
7238 1.1 mrg e->symtree->n.sym->name);
7239 1.1 mrg else
7240 1.1 mrg goto end_pointer_check;
7241 1.1 mrg
7242 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym);
7243 1.1 mrg type = TREE_TYPE (present);
7244 1.1 mrg present = fold_build2_loc (input_location, EQ_EXPR,
7245 1.1 mrg logical_type_node, present,
7246 1.1 mrg fold_convert (type,
7247 1.1 mrg null_pointer_node));
7248 1.1 mrg type = TREE_TYPE (parmse.expr);
7249 1.1 mrg null_ptr = fold_build2_loc (input_location, EQ_EXPR,
7250 1.1 mrg logical_type_node, parmse.expr,
7251 1.1 mrg fold_convert (type,
7252 1.1 mrg null_pointer_node));
7253 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
7254 1.1 mrg logical_type_node, present, null_ptr);
7255 1.1 mrg }
7256 1.1 mrg else
7257 1.1 mrg {
7258 1.1 mrg if (attr.allocatable
7259 1.1 mrg && (fsym == NULL || !fsym_attr.allocatable))
7260 1.1 mrg msg = xasprintf ("Allocatable actual argument '%s' is not "
7261 1.1 mrg "allocated", e->symtree->n.sym->name);
7262 1.1 mrg else if (attr.pointer
7263 1.1 mrg && (fsym == NULL || !fsym_attr.pointer))
7264 1.1 mrg msg = xasprintf ("Pointer actual argument '%s' is not "
7265 1.1 mrg "associated", e->symtree->n.sym->name);
7266 1.1 mrg else if (attr.proc_pointer && !e->value.function.actual
7267 1.1 mrg && (fsym == NULL || !fsym_attr.proc_pointer))
7268 1.1 mrg msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7269 1.1 mrg "associated", e->symtree->n.sym->name);
7270 1.1 mrg else
7271 1.1 mrg goto end_pointer_check;
7272 1.1 mrg
7273 1.1 mrg tmp = parmse.expr;
7274 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS)
7275 1.1 mrg {
7276 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (tmp)))
7277 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
7278 1.1 mrg tmp = gfc_class_data_get (tmp);
7279 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7280 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp);
7281 1.1 mrg }
7282 1.1 mrg
7283 1.1 mrg /* If the argument is passed by value, we need to strip the
7284 1.1 mrg INDIRECT_REF. */
7285 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
7286 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7287 1.1 mrg
7288 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR,
7289 1.1 mrg logical_type_node, tmp,
7290 1.1 mrg fold_convert (TREE_TYPE (tmp),
7291 1.1 mrg null_pointer_node));
7292 1.1 mrg }
7293 1.1 mrg
7294 1.1 mrg gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
7295 1.1 mrg msg);
7296 1.1 mrg free (msg);
7297 1.1 mrg }
7298 1.1 mrg end_pointer_check:
7299 1.1 mrg
7300 1.1 mrg /* Deferred length dummies pass the character length by reference
7301 1.1 mrg so that the value can be returned. */
7302 1.1 mrg if (parmse.string_length && fsym && fsym->ts.deferred)
7303 1.1 mrg {
7304 1.1 mrg if (INDIRECT_REF_P (parmse.string_length))
7305 1.1 mrg /* In chains of functions/procedure calls the string_length already
7306 1.1 mrg is a pointer to the variable holding the length. Therefore
7307 1.1 mrg remove the deref on call. */
7308 1.1 mrg parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
7309 1.1 mrg else
7310 1.1 mrg {
7311 1.1 mrg tmp = parmse.string_length;
7312 1.1 mrg if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
7313 1.1 mrg tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
7314 1.1 mrg parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
7315 1.1 mrg }
7316 1.1 mrg }
7317 1.1 mrg
7318 1.1 mrg /* Character strings are passed as two parameters, a length and a
7319 1.1 mrg pointer - except for Bind(c) which only passes the pointer.
7320 1.1 mrg An unlimited polymorphic formal argument likewise does not
7321 1.1 mrg need the length. */
7322 1.1 mrg if (parmse.string_length != NULL_TREE
7323 1.1 mrg && !sym->attr.is_bind_c
7324 1.1 mrg && !(fsym && UNLIMITED_POLY (fsym)))
7325 1.1 mrg vec_safe_push (stringargs, parmse.string_length);
7326 1.1 mrg
7327 1.1 mrg /* When calling __copy for character expressions to unlimited
7328 1.1 mrg polymorphic entities, the dst argument needs a string length. */
7329 1.1 mrg if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
7330 1.1 mrg && startswith (sym->name, "__vtab_CHARACTER")
7331 1.1 mrg && arg->next && arg->next->expr
7332 1.1 mrg && (arg->next->expr->ts.type == BT_DERIVED
7333 1.1 mrg || arg->next->expr->ts.type == BT_CLASS)
7334 1.1 mrg && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
7335 1.1 mrg vec_safe_push (stringargs, parmse.string_length);
7336 1.1 mrg
7337 1.1 mrg /* For descriptorless coarrays and assumed-shape coarray dummies, we
7338 1.1 mrg pass the token and the offset as additional arguments. */
7339 1.1 mrg if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
7340 1.1 mrg && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7341 1.1 mrg && !fsym->attr.allocatable)
7342 1.1 mrg || (fsym->ts.type == BT_CLASS
7343 1.1 mrg && CLASS_DATA (fsym)->attr.codimension
7344 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable)))
7345 1.1 mrg {
7346 1.1 mrg /* Token and offset. */
7347 1.1 mrg vec_safe_push (stringargs, null_pointer_node);
7348 1.1 mrg vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
7349 1.1 mrg gcc_assert (fsym->attr.optional);
7350 1.1 mrg }
7351 1.1 mrg else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
7352 1.1 mrg && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7353 1.1 mrg && !fsym->attr.allocatable)
7354 1.1 mrg || (fsym->ts.type == BT_CLASS
7355 1.1 mrg && CLASS_DATA (fsym)->attr.codimension
7356 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable)))
7357 1.1 mrg {
7358 1.1 mrg tree caf_decl, caf_type;
7359 1.1 mrg tree offset, tmp2;
7360 1.1 mrg
7361 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (e);
7362 1.1 mrg caf_type = TREE_TYPE (caf_decl);
7363 1.1 mrg
7364 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7365 1.1 mrg && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
7366 1.1 mrg || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
7367 1.1 mrg tmp = gfc_conv_descriptor_token (caf_decl);
7368 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl)
7369 1.1 mrg && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
7370 1.1 mrg tmp = GFC_DECL_TOKEN (caf_decl);
7371 1.1 mrg else
7372 1.1 mrg {
7373 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
7374 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
7375 1.1 mrg tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
7376 1.1 mrg }
7377 1.1 mrg
7378 1.1 mrg vec_safe_push (stringargs, tmp);
7379 1.1 mrg
7380 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7381 1.1 mrg && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
7382 1.1 mrg offset = build_int_cst (gfc_array_index_type, 0);
7383 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl)
7384 1.1 mrg && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
7385 1.1 mrg offset = GFC_DECL_CAF_OFFSET (caf_decl);
7386 1.1 mrg else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
7387 1.1 mrg offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
7388 1.1 mrg else
7389 1.1 mrg offset = build_int_cst (gfc_array_index_type, 0);
7390 1.1 mrg
7391 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type))
7392 1.1 mrg tmp = gfc_conv_descriptor_data_get (caf_decl);
7393 1.1 mrg else
7394 1.1 mrg {
7395 1.1 mrg gcc_assert (POINTER_TYPE_P (caf_type));
7396 1.1 mrg tmp = caf_decl;
7397 1.1 mrg }
7398 1.1 mrg
7399 1.1 mrg tmp2 = fsym->ts.type == BT_CLASS
7400 1.1 mrg ? gfc_class_data_get (parmse.expr) : parmse.expr;
7401 1.1 mrg if ((fsym->ts.type != BT_CLASS
7402 1.1 mrg && (fsym->as->type == AS_ASSUMED_SHAPE
7403 1.1 mrg || fsym->as->type == AS_ASSUMED_RANK))
7404 1.1 mrg || (fsym->ts.type == BT_CLASS
7405 1.1 mrg && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
7406 1.1 mrg || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
7407 1.1 mrg {
7408 1.1 mrg if (fsym->ts.type == BT_CLASS)
7409 1.1 mrg gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
7410 1.1 mrg else
7411 1.1 mrg {
7412 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7413 1.1 mrg tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
7414 1.1 mrg }
7415 1.1 mrg gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
7416 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (tmp2);
7417 1.1 mrg }
7418 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
7419 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (tmp2);
7420 1.1 mrg else
7421 1.1 mrg {
7422 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7423 1.1 mrg }
7424 1.1 mrg
7425 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
7426 1.1 mrg gfc_array_index_type,
7427 1.1 mrg fold_convert (gfc_array_index_type, tmp2),
7428 1.1 mrg fold_convert (gfc_array_index_type, tmp));
7429 1.1 mrg offset = fold_build2_loc (input_location, PLUS_EXPR,
7430 1.1 mrg gfc_array_index_type, offset, tmp);
7431 1.1 mrg
7432 1.1 mrg vec_safe_push (stringargs, offset);
7433 1.1 mrg }
7434 1.1 mrg
7435 1.1 mrg vec_safe_push (arglist, parmse.expr);
7436 1.1 mrg }
7437 1.1 mrg gfc_add_block_to_block (&se->pre, &clobbers);
7438 1.1 mrg gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7439 1.1 mrg
7440 1.1 mrg if (comp)
7441 1.1 mrg ts = comp->ts;
7442 1.1 mrg else if (sym->ts.type == BT_CLASS)
7443 1.1 mrg ts = CLASS_DATA (sym)->ts;
7444 1.1 mrg else
7445 1.1 mrg ts = sym->ts;
7446 1.1 mrg
7447 1.1 mrg if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7448 1.1 mrg se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7449 1.1 mrg else if (ts.type == BT_CHARACTER)
7450 1.1 mrg {
7451 1.1 mrg if (ts.u.cl->length == NULL)
7452 1.1 mrg {
7453 1.1 mrg /* Assumed character length results are not allowed by C418 of the 2003
7454 1.1 mrg standard and are trapped in resolve.cc; except in the case of SPREAD
7455 1.1 mrg (and other intrinsics?) and dummy functions. In the case of SPREAD,
7456 1.1 mrg we take the character length of the first argument for the result.
7457 1.1 mrg For dummies, we have to look through the formal argument list for
7458 1.1 mrg this function and use the character length found there.
7459 1.1 mrg Likewise, we handle the case of deferred-length character dummy
7460 1.1 mrg arguments to intrinsics that determine the characteristics of
7461 1.1 mrg the result, which cannot be deferred-length. */
7462 1.1 mrg if (expr->value.function.isym)
7463 1.1 mrg ts.deferred = false;
7464 1.1 mrg if (ts.deferred)
7465 1.1 mrg cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7466 1.1 mrg else if (!sym->attr.dummy)
7467 1.1 mrg cl.backend_decl = (*stringargs)[0];
7468 1.1 mrg else
7469 1.1 mrg {
7470 1.1 mrg formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7471 1.1 mrg for (; formal; formal = formal->next)
7472 1.1 mrg if (strcmp (formal->sym->name, sym->name) == 0)
7473 1.1 mrg cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7474 1.1 mrg }
7475 1.1 mrg len = cl.backend_decl;
7476 1.1 mrg }
7477 1.1 mrg else
7478 1.1 mrg {
7479 1.1 mrg tree tmp;
7480 1.1 mrg
7481 1.1 mrg /* Calculate the length of the returned string. */
7482 1.1 mrg gfc_init_se (&parmse, NULL);
7483 1.1 mrg if (need_interface_mapping)
7484 1.1 mrg gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
7485 1.1 mrg else
7486 1.1 mrg gfc_conv_expr (&parmse, ts.u.cl->length);
7487 1.1 mrg gfc_add_block_to_block (&se->pre, &parmse.pre);
7488 1.1 mrg gfc_add_block_to_block (&se->post, &parmse.post);
7489 1.1 mrg tmp = parmse.expr;
7490 1.1 mrg /* TODO: It would be better to have the charlens as
7491 1.1 mrg gfc_charlen_type_node already when the interface is
7492 1.1 mrg created instead of converting it here (see PR 84615). */
7493 1.1 mrg tmp = fold_build2_loc (input_location, MAX_EXPR,
7494 1.1 mrg gfc_charlen_type_node,
7495 1.1 mrg fold_convert (gfc_charlen_type_node, tmp),
7496 1.1 mrg build_zero_cst (gfc_charlen_type_node));
7497 1.1 mrg cl.backend_decl = tmp;
7498 1.1 mrg }
7499 1.1 mrg
7500 1.1 mrg /* Set up a charlen structure for it. */
7501 1.1 mrg cl.next = NULL;
7502 1.1 mrg cl.length = NULL;
7503 1.1 mrg ts.u.cl = &cl;
7504 1.1 mrg
7505 1.1 mrg len = cl.backend_decl;
7506 1.1 mrg }
7507 1.1 mrg
7508 1.1 mrg byref = (comp && (comp->attr.dimension
7509 1.1 mrg || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7510 1.1 mrg || (!comp && gfc_return_by_reference (sym));
7511 1.1 mrg if (byref)
7512 1.1 mrg {
7513 1.1 mrg if (se->direct_byref)
7514 1.1 mrg {
7515 1.1 mrg /* Sometimes, too much indirection can be applied; e.g. for
7516 1.1 mrg function_result = array_valued_recursive_function. */
7517 1.1 mrg if (TREE_TYPE (TREE_TYPE (se->expr))
7518 1.1 mrg && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7519 1.1 mrg && GFC_DESCRIPTOR_TYPE_P
7520 1.1 mrg (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
7521 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location,
7522 1.1 mrg se->expr);
7523 1.1 mrg
7524 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and
7525 1.1 mrg f2003 is allowed, we must do the automatic reallocation.
7526 1.1 mrg TODO - deal with intrinsics, without using a temporary. */
7527 1.1 mrg if (flag_realloc_lhs
7528 1.1 mrg && se->ss && se->ss->loop_chain
7529 1.1 mrg && se->ss->loop_chain->is_alloc_lhs
7530 1.1 mrg && !expr->value.function.isym
7531 1.1 mrg && sym->result->as != NULL)
7532 1.1 mrg {
7533 1.1 mrg /* Evaluate the bounds of the result, if known. */
7534 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se,
7535 1.1 mrg sym->result->as);
7536 1.1 mrg
7537 1.1 mrg /* Perform the automatic reallocation. */
7538 1.1 mrg tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7539 1.1 mrg expr, NULL);
7540 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
7541 1.1 mrg
7542 1.1 mrg /* Pass the temporary as the first argument. */
7543 1.1 mrg result = info->descriptor;
7544 1.1 mrg }
7545 1.1 mrg else
7546 1.1 mrg result = build_fold_indirect_ref_loc (input_location,
7547 1.1 mrg se->expr);
7548 1.1 mrg vec_safe_push (retargs, se->expr);
7549 1.1 mrg }
7550 1.1 mrg else if (comp && comp->attr.dimension)
7551 1.1 mrg {
7552 1.1 mrg gcc_assert (se->loop && info);
7553 1.1 mrg
7554 1.1 mrg /* Set the type of the array. */
7555 1.1 mrg tmp = gfc_typenode_for_spec (&comp->ts);
7556 1.1 mrg gcc_assert (se->ss->dimen == se->loop->dimen);
7557 1.1 mrg
7558 1.1 mrg /* Evaluate the bounds of the result, if known. */
7559 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7560 1.1 mrg
7561 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and
7562 1.1 mrg f2003 is allowed, we must not generate the function call
7563 1.1 mrg here but should just send back the results of the mapping.
7564 1.1 mrg This is signalled by the function ss being flagged. */
7565 1.1 mrg if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7566 1.1 mrg {
7567 1.1 mrg gfc_free_interface_mapping (&mapping);
7568 1.1 mrg return has_alternate_specifier;
7569 1.1 mrg }
7570 1.1 mrg
7571 1.1 mrg /* Create a temporary to store the result. In case the function
7572 1.1 mrg returns a pointer, the temporary will be a shallow copy and
7573 1.1 mrg mustn't be deallocated. */
7574 1.1 mrg callee_alloc = comp->attr.allocatable || comp->attr.pointer;
7575 1.1 mrg gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7576 1.1 mrg tmp, NULL_TREE, false,
7577 1.1 mrg !comp->attr.pointer, callee_alloc,
7578 1.1 mrg &se->ss->info->expr->where);
7579 1.1 mrg
7580 1.1 mrg /* Pass the temporary as the first argument. */
7581 1.1 mrg result = info->descriptor;
7582 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, result);
7583 1.1 mrg vec_safe_push (retargs, tmp);
7584 1.1 mrg }
7585 1.1 mrg else if (!comp && sym->result->attr.dimension)
7586 1.1 mrg {
7587 1.1 mrg gcc_assert (se->loop && info);
7588 1.1 mrg
7589 1.1 mrg /* Set the type of the array. */
7590 1.1 mrg tmp = gfc_typenode_for_spec (&ts);
7591 1.1 mrg gcc_assert (se->ss->dimen == se->loop->dimen);
7592 1.1 mrg
7593 1.1 mrg /* Evaluate the bounds of the result, if known. */
7594 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7595 1.1 mrg
7596 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and
7597 1.1 mrg f2003 is allowed, we must not generate the function call
7598 1.1 mrg here but should just send back the results of the mapping.
7599 1.1 mrg This is signalled by the function ss being flagged. */
7600 1.1 mrg if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7601 1.1 mrg {
7602 1.1 mrg gfc_free_interface_mapping (&mapping);
7603 1.1 mrg return has_alternate_specifier;
7604 1.1 mrg }
7605 1.1 mrg
7606 1.1 mrg /* Create a temporary to store the result. In case the function
7607 1.1 mrg returns a pointer, the temporary will be a shallow copy and
7608 1.1 mrg mustn't be deallocated. */
7609 1.1 mrg callee_alloc = sym->attr.allocatable || sym->attr.pointer;
7610 1.1 mrg gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7611 1.1 mrg tmp, NULL_TREE, false,
7612 1.1 mrg !sym->attr.pointer, callee_alloc,
7613 1.1 mrg &se->ss->info->expr->where);
7614 1.1 mrg
7615 1.1 mrg /* Pass the temporary as the first argument. */
7616 1.1 mrg result = info->descriptor;
7617 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, result);
7618 1.1 mrg vec_safe_push (retargs, tmp);
7619 1.1 mrg }
7620 1.1 mrg else if (ts.type == BT_CHARACTER)
7621 1.1 mrg {
7622 1.1 mrg /* Pass the string length. */
7623 1.1 mrg type = gfc_get_character_type (ts.kind, ts.u.cl);
7624 1.1 mrg type = build_pointer_type (type);
7625 1.1 mrg
7626 1.1 mrg /* Emit a DECL_EXPR for the VLA type. */
7627 1.1 mrg tmp = TREE_TYPE (type);
7628 1.1 mrg if (TYPE_SIZE (tmp)
7629 1.1 mrg && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7630 1.1 mrg {
7631 1.1 mrg tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7632 1.1 mrg DECL_ARTIFICIAL (tmp) = 1;
7633 1.1 mrg DECL_IGNORED_P (tmp) = 1;
7634 1.1 mrg tmp = fold_build1_loc (input_location, DECL_EXPR,
7635 1.1 mrg TREE_TYPE (tmp), tmp);
7636 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
7637 1.1 mrg }
7638 1.1 mrg
7639 1.1 mrg /* Return an address to a char[0:len-1]* temporary for
7640 1.1 mrg character pointers. */
7641 1.1 mrg if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7642 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7643 1.1 mrg {
7644 1.1 mrg var = gfc_create_var (type, "pstr");
7645 1.1 mrg
7646 1.1 mrg if ((!comp && sym->attr.allocatable)
7647 1.1 mrg || (comp && comp->attr.allocatable))
7648 1.1 mrg {
7649 1.1 mrg gfc_add_modify (&se->pre, var,
7650 1.1 mrg fold_convert (TREE_TYPE (var),
7651 1.1 mrg null_pointer_node));
7652 1.1 mrg tmp = gfc_call_free (var);
7653 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
7654 1.1 mrg }
7655 1.1 mrg
7656 1.1 mrg /* Provide an address expression for the function arguments. */
7657 1.1 mrg var = gfc_build_addr_expr (NULL_TREE, var);
7658 1.1 mrg }
7659 1.1 mrg else
7660 1.1 mrg var = gfc_conv_string_tmp (se, type, len);
7661 1.1 mrg
7662 1.1 mrg vec_safe_push (retargs, var);
7663 1.1 mrg }
7664 1.1 mrg else
7665 1.1 mrg {
7666 1.1 mrg gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
7667 1.1 mrg
7668 1.1 mrg type = gfc_get_complex_type (ts.kind);
7669 1.1 mrg var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
7670 1.1 mrg vec_safe_push (retargs, var);
7671 1.1 mrg }
7672 1.1 mrg
7673 1.1 mrg /* Add the string length to the argument list. */
7674 1.1 mrg if (ts.type == BT_CHARACTER && ts.deferred)
7675 1.1 mrg {
7676 1.1 mrg tmp = len;
7677 1.1 mrg if (!VAR_P (tmp))
7678 1.1 mrg tmp = gfc_evaluate_now (len, &se->pre);
7679 1.1 mrg TREE_STATIC (tmp) = 1;
7680 1.1 mrg gfc_add_modify (&se->pre, tmp,
7681 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0));
7682 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7683 1.1 mrg vec_safe_push (retargs, tmp);
7684 1.1 mrg }
7685 1.1 mrg else if (ts.type == BT_CHARACTER)
7686 1.1 mrg vec_safe_push (retargs, len);
7687 1.1 mrg }
7688 1.1 mrg gfc_free_interface_mapping (&mapping);
7689 1.1 mrg
7690 1.1 mrg /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
7691 1.1 mrg arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7692 1.1 mrg + vec_safe_length (stringargs) + vec_safe_length (append_args));
7693 1.1 mrg vec_safe_reserve (retargs, arglen);
7694 1.1 mrg
7695 1.1 mrg /* Add the return arguments. */
7696 1.1 mrg vec_safe_splice (retargs, arglist);
7697 1.1 mrg
7698 1.1 mrg /* Add the hidden present status for optional+value to the arguments. */
7699 1.1 mrg vec_safe_splice (retargs, optionalargs);
7700 1.1 mrg
7701 1.1 mrg /* Add the hidden string length parameters to the arguments. */
7702 1.1 mrg vec_safe_splice (retargs, stringargs);
7703 1.1 mrg
7704 1.1 mrg /* We may want to append extra arguments here. This is used e.g. for
7705 1.1 mrg calls to libgfortran_matmul_??, which need extra information. */
7706 1.1 mrg vec_safe_splice (retargs, append_args);
7707 1.1 mrg
7708 1.1 mrg arglist = retargs;
7709 1.1 mrg
7710 1.1 mrg /* Generate the actual call. */
7711 1.1 mrg if (base_object == NULL_TREE)
7712 1.1 mrg conv_function_val (se, sym, expr, args);
7713 1.1 mrg else
7714 1.1 mrg conv_base_obj_fcn_val (se, base_object, expr);
7715 1.1 mrg
7716 1.1 mrg /* If there are alternate return labels, function type should be
7717 1.1 mrg integer. Can't modify the type in place though, since it can be shared
7718 1.1 mrg with other functions. For dummy arguments, the typing is done to
7719 1.1 mrg this result, even if it has to be repeated for each call. */
7720 1.1 mrg if (has_alternate_specifier
7721 1.1 mrg && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7722 1.1 mrg {
7723 1.1 mrg if (!sym->attr.dummy)
7724 1.1 mrg {
7725 1.1 mrg TREE_TYPE (sym->backend_decl)
7726 1.1 mrg = build_function_type (integer_type_node,
7727 1.1 mrg TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
7728 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
7729 1.1 mrg }
7730 1.1 mrg else
7731 1.1 mrg TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
7732 1.1 mrg }
7733 1.1 mrg
7734 1.1 mrg fntype = TREE_TYPE (TREE_TYPE (se->expr));
7735 1.1 mrg se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
7736 1.1 mrg
7737 1.1 mrg /* Allocatable scalar function results must be freed and nullified
7738 1.1 mrg after use. This necessitates the creation of a temporary to
7739 1.1 mrg hold the result to prevent duplicate calls. */
7740 1.1 mrg if (!byref && sym->ts.type != BT_CHARACTER
7741 1.1 mrg && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
7742 1.1 mrg || (comp && comp->attr.allocatable && !comp->attr.dimension)))
7743 1.1 mrg {
7744 1.1 mrg tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7745 1.1 mrg gfc_add_modify (&se->pre, tmp, se->expr);
7746 1.1 mrg se->expr = tmp;
7747 1.1 mrg tmp = gfc_call_free (tmp);
7748 1.1 mrg gfc_add_expr_to_block (&post, tmp);
7749 1.1 mrg gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7750 1.1 mrg }
7751 1.1 mrg
7752 1.1 mrg /* If we have a pointer function, but we don't want a pointer, e.g.
7753 1.1 mrg something like
7754 1.1 mrg x = f()
7755 1.1 mrg where f is pointer valued, we have to dereference the result. */
7756 1.1 mrg if (!se->want_pointer && !byref
7757 1.1 mrg && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7758 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7759 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7760 1.1 mrg
7761 1.1 mrg /* f2c calling conventions require a scalar default real function to
7762 1.1 mrg return a double precision result. Convert this back to default
7763 1.1 mrg real. We only care about the cases that can happen in Fortran 77.
7764 1.1 mrg */
7765 1.1 mrg if (flag_f2c && sym->ts.type == BT_REAL
7766 1.1 mrg && sym->ts.kind == gfc_default_real_kind
7767 1.1 mrg && !sym->attr.always_explicit)
7768 1.1 mrg se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7769 1.1 mrg
7770 1.1 mrg /* A pure function may still have side-effects - it may modify its
7771 1.1 mrg parameters. */
7772 1.1 mrg TREE_SIDE_EFFECTS (se->expr) = 1;
7773 1.1 mrg #if 0
7774 1.1 mrg if (!sym->attr.pure)
7775 1.1 mrg TREE_SIDE_EFFECTS (se->expr) = 1;
7776 1.1 mrg #endif
7777 1.1 mrg
7778 1.1 mrg if (byref)
7779 1.1 mrg {
7780 1.1 mrg /* Add the function call to the pre chain. There is no expression. */
7781 1.1 mrg gfc_add_expr_to_block (&se->pre, se->expr);
7782 1.1 mrg se->expr = NULL_TREE;
7783 1.1 mrg
7784 1.1 mrg if (!se->direct_byref)
7785 1.1 mrg {
7786 1.1 mrg if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
7787 1.1 mrg {
7788 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
7789 1.1 mrg {
7790 1.1 mrg /* Check the data pointer hasn't been modified. This would
7791 1.1 mrg happen in a function returning a pointer. */
7792 1.1 mrg tmp = gfc_conv_descriptor_data_get (info->descriptor);
7793 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
7794 1.1 mrg logical_type_node,
7795 1.1 mrg tmp, info->data);
7796 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
7797 1.1 mrg gfc_msg_fault);
7798 1.1 mrg }
7799 1.1 mrg se->expr = info->descriptor;
7800 1.1 mrg /* Bundle in the string length. */
7801 1.1 mrg se->string_length = len;
7802 1.1 mrg }
7803 1.1 mrg else if (ts.type == BT_CHARACTER)
7804 1.1 mrg {
7805 1.1 mrg /* Dereference for character pointer results. */
7806 1.1 mrg if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7807 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7808 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, var);
7809 1.1 mrg else
7810 1.1 mrg se->expr = var;
7811 1.1 mrg
7812 1.1 mrg se->string_length = len;
7813 1.1 mrg }
7814 1.1 mrg else
7815 1.1 mrg {
7816 1.1 mrg gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
7817 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, var);
7818 1.1 mrg }
7819 1.1 mrg }
7820 1.1 mrg }
7821 1.1 mrg
7822 1.1 mrg /* Associate the rhs class object's meta-data with the result, when the
7823 1.1 mrg result is a temporary. */
7824 1.1 mrg if (args && args->expr && args->expr->ts.type == BT_CLASS
7825 1.1 mrg && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
7826 1.1 mrg && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
7827 1.1 mrg {
7828 1.1 mrg gfc_se parmse;
7829 1.1 mrg gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
7830 1.1 mrg
7831 1.1 mrg gfc_init_se (&parmse, NULL);
7832 1.1 mrg parmse.data_not_needed = 1;
7833 1.1 mrg gfc_conv_expr (&parmse, class_expr);
7834 1.1 mrg if (!DECL_LANG_SPECIFIC (result))
7835 1.1 mrg gfc_allocate_lang_decl (result);
7836 1.1 mrg GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
7837 1.1 mrg gfc_free_expr (class_expr);
7838 1.1 mrg /* -fcheck= can add diagnostic code, which has to be placed before
7839 1.1 mrg the call. */
7840 1.1 mrg if (parmse.pre.head != NULL)
7841 1.1 mrg gfc_add_expr_to_block (&se->pre, parmse.pre.head);
7842 1.1 mrg gcc_assert (parmse.post.head == NULL_TREE);
7843 1.1 mrg }
7844 1.1 mrg
7845 1.1 mrg /* Follow the function call with the argument post block. */
7846 1.1 mrg if (byref)
7847 1.1 mrg {
7848 1.1 mrg gfc_add_block_to_block (&se->pre, &post);
7849 1.1 mrg
7850 1.1 mrg /* Transformational functions of derived types with allocatable
7851 1.1 mrg components must have the result allocatable components copied when the
7852 1.1 mrg argument is actually given. */
7853 1.1 mrg arg = expr->value.function.actual;
7854 1.1 mrg if (result && arg && expr->rank
7855 1.1 mrg && expr->value.function.isym
7856 1.1 mrg && expr->value.function.isym->transformational
7857 1.1 mrg && arg->expr
7858 1.1 mrg && arg->expr->ts.type == BT_DERIVED
7859 1.1 mrg && arg->expr->ts.u.derived->attr.alloc_comp)
7860 1.1 mrg {
7861 1.1 mrg tree tmp2;
7862 1.1 mrg /* Copy the allocatable components. We have to use a
7863 1.1 mrg temporary here to prevent source allocatable components
7864 1.1 mrg from being corrupted. */
7865 1.1 mrg tmp2 = gfc_evaluate_now (result, &se->pre);
7866 1.1 mrg tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
7867 1.1 mrg result, tmp2, expr->rank, 0);
7868 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
7869 1.1 mrg tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
7870 1.1 mrg expr->rank);
7871 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
7872 1.1 mrg
7873 1.1 mrg /* Finally free the temporary's data field. */
7874 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp2);
7875 1.1 mrg tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7876 1.1 mrg NULL_TREE, NULL_TREE, true,
7877 1.1 mrg NULL, GFC_CAF_COARRAY_NOCOARRAY);
7878 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
7879 1.1 mrg }
7880 1.1 mrg }
7881 1.1 mrg else
7882 1.1 mrg {
7883 1.1 mrg /* For a function with a class array result, save the result as
7884 1.1 mrg a temporary, set the info fields needed by the scalarizer and
7885 1.1 mrg call the finalization function of the temporary. Note that the
7886 1.1 mrg nullification of allocatable components needed by the result
7887 1.1 mrg is done in gfc_trans_assignment_1. */
7888 1.1 mrg if (expr && ((gfc_is_class_array_function (expr)
7889 1.1 mrg && se->ss && se->ss->loop)
7890 1.1 mrg || gfc_is_alloc_class_scalar_function (expr))
7891 1.1 mrg && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
7892 1.1 mrg && expr->must_finalize)
7893 1.1 mrg {
7894 1.1 mrg tree final_fndecl;
7895 1.1 mrg tree is_final;
7896 1.1 mrg int n;
7897 1.1 mrg if (se->ss && se->ss->loop)
7898 1.1 mrg {
7899 1.1 mrg gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
7900 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
7901 1.1 mrg tmp = gfc_class_data_get (se->expr);
7902 1.1 mrg info->descriptor = tmp;
7903 1.1 mrg info->data = gfc_conv_descriptor_data_get (tmp);
7904 1.1 mrg info->offset = gfc_conv_descriptor_offset_get (tmp);
7905 1.1 mrg for (n = 0; n < se->ss->loop->dimen; n++)
7906 1.1 mrg {
7907 1.1 mrg tree dim = gfc_rank_cst[n];
7908 1.1 mrg se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
7909 1.1 mrg se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
7910 1.1 mrg }
7911 1.1 mrg }
7912 1.1 mrg else
7913 1.1 mrg {
7914 1.1 mrg /* TODO Eliminate the doubling of temporaries. This
7915 1.1 mrg one is necessary to ensure no memory leakage. */
7916 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre);
7917 1.1 mrg tmp = gfc_class_data_get (se->expr);
7918 1.1 mrg tmp = gfc_conv_scalar_to_descriptor (se, tmp,
7919 1.1 mrg CLASS_DATA (expr->value.function.esym->result)->attr);
7920 1.1 mrg }
7921 1.1 mrg
7922 1.1 mrg if ((gfc_is_class_array_function (expr)
7923 1.1 mrg || gfc_is_alloc_class_scalar_function (expr))
7924 1.1 mrg && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
7925 1.1 mrg goto no_finalization;
7926 1.1 mrg
7927 1.1 mrg final_fndecl = gfc_class_vtab_final_get (se->expr);
7928 1.1 mrg is_final = fold_build2_loc (input_location, NE_EXPR,
7929 1.1 mrg logical_type_node,
7930 1.1 mrg final_fndecl,
7931 1.1 mrg fold_convert (TREE_TYPE (final_fndecl),
7932 1.1 mrg null_pointer_node));
7933 1.1 mrg final_fndecl = build_fold_indirect_ref_loc (input_location,
7934 1.1 mrg final_fndecl);
7935 1.1 mrg tmp = build_call_expr_loc (input_location,
7936 1.1 mrg final_fndecl, 3,
7937 1.1 mrg gfc_build_addr_expr (NULL, tmp),
7938 1.1 mrg gfc_class_vtab_size_get (se->expr),
7939 1.1 mrg boolean_false_node);
7940 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
7941 1.1 mrg void_type_node, is_final, tmp,
7942 1.1 mrg build_empty_stmt (input_location));
7943 1.1 mrg
7944 1.1 mrg if (se->ss && se->ss->loop)
7945 1.1 mrg {
7946 1.1 mrg gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
7947 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
7948 1.1 mrg logical_type_node,
7949 1.1 mrg info->data,
7950 1.1 mrg fold_convert (TREE_TYPE (info->data),
7951 1.1 mrg null_pointer_node));
7952 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
7953 1.1 mrg void_type_node, tmp,
7954 1.1 mrg gfc_call_free (info->data),
7955 1.1 mrg build_empty_stmt (input_location));
7956 1.1 mrg gfc_add_expr_to_block (&se->ss->loop->post, tmp);
7957 1.1 mrg }
7958 1.1 mrg else
7959 1.1 mrg {
7960 1.1 mrg tree classdata;
7961 1.1 mrg gfc_prepend_expr_to_block (&se->post, tmp);
7962 1.1 mrg classdata = gfc_class_data_get (se->expr);
7963 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
7964 1.1 mrg logical_type_node,
7965 1.1 mrg classdata,
7966 1.1 mrg fold_convert (TREE_TYPE (classdata),
7967 1.1 mrg null_pointer_node));
7968 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR,
7969 1.1 mrg void_type_node, tmp,
7970 1.1 mrg gfc_call_free (classdata),
7971 1.1 mrg build_empty_stmt (input_location));
7972 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
7973 1.1 mrg }
7974 1.1 mrg }
7975 1.1 mrg
7976 1.1 mrg no_finalization:
7977 1.1 mrg gfc_add_block_to_block (&se->post, &post);
7978 1.1 mrg }
7979 1.1 mrg
7980 1.1 mrg return has_alternate_specifier;
7981 1.1 mrg }
7982 1.1 mrg
7983 1.1 mrg
7984 1.1 mrg /* Fill a character string with spaces. */
7985 1.1 mrg
7986 1.1 mrg static tree
7987 1.1 mrg fill_with_spaces (tree start, tree type, tree size)
7988 1.1 mrg {
7989 1.1 mrg stmtblock_t block, loop;
7990 1.1 mrg tree i, el, exit_label, cond, tmp;
7991 1.1 mrg
7992 1.1 mrg /* For a simple char type, we can call memset(). */
7993 1.1 mrg if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
7994 1.1 mrg return build_call_expr_loc (input_location,
7995 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMSET),
7996 1.1 mrg 3, start,
7997 1.1 mrg build_int_cst (gfc_get_int_type (gfc_c_int_kind),
7998 1.1 mrg lang_hooks.to_target_charset (' ')),
7999 1.1 mrg fold_convert (size_type_node, size));
8000 1.1 mrg
8001 1.1 mrg /* Otherwise, we use a loop:
8002 1.1 mrg for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
8003 1.1 mrg *el = (type) ' ';
8004 1.1 mrg */
8005 1.1 mrg
8006 1.1 mrg /* Initialize variables. */
8007 1.1 mrg gfc_init_block (&block);
8008 1.1 mrg i = gfc_create_var (sizetype, "i");
8009 1.1 mrg gfc_add_modify (&block, i, fold_convert (sizetype, size));
8010 1.1 mrg el = gfc_create_var (build_pointer_type (type), "el");
8011 1.1 mrg gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
8012 1.1 mrg exit_label = gfc_build_label_decl (NULL_TREE);
8013 1.1 mrg TREE_USED (exit_label) = 1;
8014 1.1 mrg
8015 1.1 mrg
8016 1.1 mrg /* Loop body. */
8017 1.1 mrg gfc_init_block (&loop);
8018 1.1 mrg
8019 1.1 mrg /* Exit condition. */
8020 1.1 mrg cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
8021 1.1 mrg build_zero_cst (sizetype));
8022 1.1 mrg tmp = build1_v (GOTO_EXPR, exit_label);
8023 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8024 1.1 mrg build_empty_stmt (input_location));
8025 1.1 mrg gfc_add_expr_to_block (&loop, tmp);
8026 1.1 mrg
8027 1.1 mrg /* Assignment. */
8028 1.1 mrg gfc_add_modify (&loop,
8029 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF, type, el),
8030 1.1 mrg build_int_cst (type, lang_hooks.to_target_charset (' ')));
8031 1.1 mrg
8032 1.1 mrg /* Increment loop variables. */
8033 1.1 mrg gfc_add_modify (&loop, i,
8034 1.1 mrg fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
8035 1.1 mrg TYPE_SIZE_UNIT (type)));
8036 1.1 mrg gfc_add_modify (&loop, el,
8037 1.1 mrg fold_build_pointer_plus_loc (input_location,
8038 1.1 mrg el, TYPE_SIZE_UNIT (type)));
8039 1.1 mrg
8040 1.1 mrg /* Making the loop... actually loop! */
8041 1.1 mrg tmp = gfc_finish_block (&loop);
8042 1.1 mrg tmp = build1_v (LOOP_EXPR, tmp);
8043 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8044 1.1 mrg
8045 1.1 mrg /* The exit label. */
8046 1.1 mrg tmp = build1_v (LABEL_EXPR, exit_label);
8047 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8048 1.1 mrg
8049 1.1 mrg
8050 1.1 mrg return gfc_finish_block (&block);
8051 1.1 mrg }
8052 1.1 mrg
8053 1.1 mrg
8054 1.1 mrg /* Generate code to copy a string. */
8055 1.1 mrg
8056 1.1 mrg void
8057 1.1 mrg gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
8058 1.1 mrg int dkind, tree slength, tree src, int skind)
8059 1.1 mrg {
8060 1.1 mrg tree tmp, dlen, slen;
8061 1.1 mrg tree dsc;
8062 1.1 mrg tree ssc;
8063 1.1 mrg tree cond;
8064 1.1 mrg tree cond2;
8065 1.1 mrg tree tmp2;
8066 1.1 mrg tree tmp3;
8067 1.1 mrg tree tmp4;
8068 1.1 mrg tree chartype;
8069 1.1 mrg stmtblock_t tempblock;
8070 1.1 mrg
8071 1.1 mrg gcc_assert (dkind == skind);
8072 1.1 mrg
8073 1.1 mrg if (slength != NULL_TREE)
8074 1.1 mrg {
8075 1.1 mrg slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
8076 1.1 mrg ssc = gfc_string_to_single_character (slen, src, skind);
8077 1.1 mrg }
8078 1.1 mrg else
8079 1.1 mrg {
8080 1.1 mrg slen = build_one_cst (gfc_charlen_type_node);
8081 1.1 mrg ssc = src;
8082 1.1 mrg }
8083 1.1 mrg
8084 1.1 mrg if (dlength != NULL_TREE)
8085 1.1 mrg {
8086 1.1 mrg dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
8087 1.1 mrg dsc = gfc_string_to_single_character (dlen, dest, dkind);
8088 1.1 mrg }
8089 1.1 mrg else
8090 1.1 mrg {
8091 1.1 mrg dlen = build_one_cst (gfc_charlen_type_node);
8092 1.1 mrg dsc = dest;
8093 1.1 mrg }
8094 1.1 mrg
8095 1.1 mrg /* Assign directly if the types are compatible. */
8096 1.1 mrg if (dsc != NULL_TREE && ssc != NULL_TREE
8097 1.1 mrg && TREE_TYPE (dsc) == TREE_TYPE (ssc))
8098 1.1 mrg {
8099 1.1 mrg gfc_add_modify (block, dsc, ssc);
8100 1.1 mrg return;
8101 1.1 mrg }
8102 1.1 mrg
8103 1.1 mrg /* The string copy algorithm below generates code like
8104 1.1 mrg
8105 1.1 mrg if (destlen > 0)
8106 1.1 mrg {
8107 1.1 mrg if (srclen < destlen)
8108 1.1 mrg {
8109 1.1 mrg memmove (dest, src, srclen);
8110 1.1 mrg // Pad with spaces.
8111 1.1 mrg memset (&dest[srclen], ' ', destlen - srclen);
8112 1.1 mrg }
8113 1.1 mrg else
8114 1.1 mrg {
8115 1.1 mrg // Truncate if too long.
8116 1.1 mrg memmove (dest, src, destlen);
8117 1.1 mrg }
8118 1.1 mrg }
8119 1.1 mrg */
8120 1.1 mrg
8121 1.1 mrg /* Do nothing if the destination length is zero. */
8122 1.1 mrg cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
8123 1.1 mrg build_zero_cst (TREE_TYPE (dlen)));
8124 1.1 mrg
8125 1.1 mrg /* For non-default character kinds, we have to multiply the string
8126 1.1 mrg length by the base type size. */
8127 1.1 mrg chartype = gfc_get_char_type (dkind);
8128 1.1 mrg slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
8129 1.1 mrg slen,
8130 1.1 mrg fold_convert (TREE_TYPE (slen),
8131 1.1 mrg TYPE_SIZE_UNIT (chartype)));
8132 1.1 mrg dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
8133 1.1 mrg dlen,
8134 1.1 mrg fold_convert (TREE_TYPE (dlen),
8135 1.1 mrg TYPE_SIZE_UNIT (chartype)));
8136 1.1 mrg
8137 1.1 mrg if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
8138 1.1 mrg dest = fold_convert (pvoid_type_node, dest);
8139 1.1 mrg else
8140 1.1 mrg dest = gfc_build_addr_expr (pvoid_type_node, dest);
8141 1.1 mrg
8142 1.1 mrg if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
8143 1.1 mrg src = fold_convert (pvoid_type_node, src);
8144 1.1 mrg else
8145 1.1 mrg src = gfc_build_addr_expr (pvoid_type_node, src);
8146 1.1 mrg
8147 1.1 mrg /* Truncate string if source is too long. */
8148 1.1 mrg cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
8149 1.1 mrg dlen);
8150 1.1 mrg
8151 1.1 mrg /* Pre-evaluate pointers unless one of the IF arms will be optimized away. */
8152 1.1 mrg if (!CONSTANT_CLASS_P (cond2))
8153 1.1 mrg {
8154 1.1 mrg dest = gfc_evaluate_now (dest, block);
8155 1.1 mrg src = gfc_evaluate_now (src, block);
8156 1.1 mrg }
8157 1.1 mrg
8158 1.1 mrg /* Copy and pad with spaces. */
8159 1.1 mrg tmp3 = build_call_expr_loc (input_location,
8160 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMMOVE),
8161 1.1 mrg 3, dest, src,
8162 1.1 mrg fold_convert (size_type_node, slen));
8163 1.1 mrg
8164 1.1 mrg /* Wstringop-overflow appears at -O3 even though this warning is not
8165 1.1 mrg explicitly available in fortran nor can it be switched off. If the
8166 1.1 mrg source length is a constant, its negative appears as a very large
8167 1.1 mrg postive number and triggers the warning in BUILTIN_MEMSET. Fixing
8168 1.1 mrg the result of the MINUS_EXPR suppresses this spurious warning. */
8169 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
8170 1.1 mrg TREE_TYPE(dlen), dlen, slen);
8171 1.1 mrg if (slength && TREE_CONSTANT (slength))
8172 1.1 mrg tmp = gfc_evaluate_now (tmp, block);
8173 1.1 mrg
8174 1.1 mrg tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
8175 1.1 mrg tmp4 = fill_with_spaces (tmp4, chartype, tmp);
8176 1.1 mrg
8177 1.1 mrg gfc_init_block (&tempblock);
8178 1.1 mrg gfc_add_expr_to_block (&tempblock, tmp3);
8179 1.1 mrg gfc_add_expr_to_block (&tempblock, tmp4);
8180 1.1 mrg tmp3 = gfc_finish_block (&tempblock);
8181 1.1 mrg
8182 1.1 mrg /* The truncated memmove if the slen >= dlen. */
8183 1.1 mrg tmp2 = build_call_expr_loc (input_location,
8184 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMMOVE),
8185 1.1 mrg 3, dest, src,
8186 1.1 mrg fold_convert (size_type_node, dlen));
8187 1.1 mrg
8188 1.1 mrg /* The whole copy_string function is there. */
8189 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
8190 1.1 mrg tmp3, tmp2);
8191 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8192 1.1 mrg build_empty_stmt (input_location));
8193 1.1 mrg gfc_add_expr_to_block (block, tmp);
8194 1.1 mrg }
8195 1.1 mrg
8196 1.1 mrg
8197 1.1 mrg /* Translate a statement function.
8198 1.1 mrg The value of a statement function reference is obtained by evaluating the
8199 1.1 mrg expression using the values of the actual arguments for the values of the
8200 1.1 mrg corresponding dummy arguments. */
8201 1.1 mrg
8202 1.1 mrg static void
8203 1.1 mrg gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
8204 1.1 mrg {
8205 1.1 mrg gfc_symbol *sym;
8206 1.1 mrg gfc_symbol *fsym;
8207 1.1 mrg gfc_formal_arglist *fargs;
8208 1.1 mrg gfc_actual_arglist *args;
8209 1.1 mrg gfc_se lse;
8210 1.1 mrg gfc_se rse;
8211 1.1 mrg gfc_saved_var *saved_vars;
8212 1.1 mrg tree *temp_vars;
8213 1.1 mrg tree type;
8214 1.1 mrg tree tmp;
8215 1.1 mrg int n;
8216 1.1 mrg
8217 1.1 mrg sym = expr->symtree->n.sym;
8218 1.1 mrg args = expr->value.function.actual;
8219 1.1 mrg gfc_init_se (&lse, NULL);
8220 1.1 mrg gfc_init_se (&rse, NULL);
8221 1.1 mrg
8222 1.1 mrg n = 0;
8223 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
8224 1.1 mrg n++;
8225 1.1 mrg saved_vars = XCNEWVEC (gfc_saved_var, n);
8226 1.1 mrg temp_vars = XCNEWVEC (tree, n);
8227 1.1 mrg
8228 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8229 1.1 mrg fargs = fargs->next, n++)
8230 1.1 mrg {
8231 1.1 mrg /* Each dummy shall be specified, explicitly or implicitly, to be
8232 1.1 mrg scalar. */
8233 1.1 mrg gcc_assert (fargs->sym->attr.dimension == 0);
8234 1.1 mrg fsym = fargs->sym;
8235 1.1 mrg
8236 1.1 mrg if (fsym->ts.type == BT_CHARACTER)
8237 1.1 mrg {
8238 1.1 mrg /* Copy string arguments. */
8239 1.1 mrg tree arglen;
8240 1.1 mrg
8241 1.1 mrg gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
8242 1.1 mrg && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
8243 1.1 mrg
8244 1.1 mrg /* Create a temporary to hold the value. */
8245 1.1 mrg if (fsym->ts.u.cl->backend_decl == NULL_TREE)
8246 1.1 mrg fsym->ts.u.cl->backend_decl
8247 1.1 mrg = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
8248 1.1 mrg
8249 1.1 mrg type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
8250 1.1 mrg temp_vars[n] = gfc_create_var (type, fsym->name);
8251 1.1 mrg
8252 1.1 mrg arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8253 1.1 mrg
8254 1.1 mrg gfc_conv_expr (&rse, args->expr);
8255 1.1 mrg gfc_conv_string_parameter (&rse);
8256 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre);
8257 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre);
8258 1.1 mrg
8259 1.1 mrg gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
8260 1.1 mrg rse.string_length, rse.expr, fsym->ts.kind);
8261 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post);
8262 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.post);
8263 1.1 mrg }
8264 1.1 mrg else
8265 1.1 mrg {
8266 1.1 mrg /* For everything else, just evaluate the expression. */
8267 1.1 mrg
8268 1.1 mrg /* Create a temporary to hold the value. */
8269 1.1 mrg type = gfc_typenode_for_spec (&fsym->ts);
8270 1.1 mrg temp_vars[n] = gfc_create_var (type, fsym->name);
8271 1.1 mrg
8272 1.1 mrg gfc_conv_expr (&lse, args->expr);
8273 1.1 mrg
8274 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre);
8275 1.1 mrg gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
8276 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post);
8277 1.1 mrg }
8278 1.1 mrg
8279 1.1 mrg args = args->next;
8280 1.1 mrg }
8281 1.1 mrg
8282 1.1 mrg /* Use the temporary variables in place of the real ones. */
8283 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8284 1.1 mrg fargs = fargs->next, n++)
8285 1.1 mrg gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
8286 1.1 mrg
8287 1.1 mrg gfc_conv_expr (se, sym->value);
8288 1.1 mrg
8289 1.1 mrg if (sym->ts.type == BT_CHARACTER)
8290 1.1 mrg {
8291 1.1 mrg gfc_conv_const_charlen (sym->ts.u.cl);
8292 1.1 mrg
8293 1.1 mrg /* Force the expression to the correct length. */
8294 1.1 mrg if (!INTEGER_CST_P (se->string_length)
8295 1.1 mrg || tree_int_cst_lt (se->string_length,
8296 1.1 mrg sym->ts.u.cl->backend_decl))
8297 1.1 mrg {
8298 1.1 mrg type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
8299 1.1 mrg tmp = gfc_create_var (type, sym->name);
8300 1.1 mrg tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
8301 1.1 mrg gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
8302 1.1 mrg sym->ts.kind, se->string_length, se->expr,
8303 1.1 mrg sym->ts.kind);
8304 1.1 mrg se->expr = tmp;
8305 1.1 mrg }
8306 1.1 mrg se->string_length = sym->ts.u.cl->backend_decl;
8307 1.1 mrg }
8308 1.1 mrg
8309 1.1 mrg /* Restore the original variables. */
8310 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8311 1.1 mrg fargs = fargs->next, n++)
8312 1.1 mrg gfc_restore_sym (fargs->sym, &saved_vars[n]);
8313 1.1 mrg free (temp_vars);
8314 1.1 mrg free (saved_vars);
8315 1.1 mrg }
8316 1.1 mrg
8317 1.1 mrg
8318 1.1 mrg /* Translate a function expression. */
8319 1.1 mrg
8320 1.1 mrg static void
8321 1.1 mrg gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
8322 1.1 mrg {
8323 1.1 mrg gfc_symbol *sym;
8324 1.1 mrg
8325 1.1 mrg if (expr->value.function.isym)
8326 1.1 mrg {
8327 1.1 mrg gfc_conv_intrinsic_function (se, expr);
8328 1.1 mrg return;
8329 1.1 mrg }
8330 1.1 mrg
8331 1.1 mrg /* expr.value.function.esym is the resolved (specific) function symbol for
8332 1.1 mrg most functions. However this isn't set for dummy procedures. */
8333 1.1 mrg sym = expr->value.function.esym;
8334 1.1 mrg if (!sym)
8335 1.1 mrg sym = expr->symtree->n.sym;
8336 1.1 mrg
8337 1.1 mrg /* The IEEE_ARITHMETIC functions are caught here. */
8338 1.1 mrg if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
8339 1.1 mrg if (gfc_conv_ieee_arithmetic_function (se, expr))
8340 1.1 mrg return;
8341 1.1 mrg
8342 1.1 mrg /* We distinguish statement functions from general functions to improve
8343 1.1 mrg runtime performance. */
8344 1.1 mrg if (sym->attr.proc == PROC_ST_FUNCTION)
8345 1.1 mrg {
8346 1.1 mrg gfc_conv_statement_function (se, expr);
8347 1.1 mrg return;
8348 1.1 mrg }
8349 1.1 mrg
8350 1.1 mrg gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
8351 1.1 mrg NULL);
8352 1.1 mrg }
8353 1.1 mrg
8354 1.1 mrg
8355 1.1 mrg /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
8356 1.1 mrg
8357 1.1 mrg static bool
8358 1.1 mrg is_zero_initializer_p (gfc_expr * expr)
8359 1.1 mrg {
8360 1.1 mrg if (expr->expr_type != EXPR_CONSTANT)
8361 1.1 mrg return false;
8362 1.1 mrg
8363 1.1 mrg /* We ignore constants with prescribed memory representations for now. */
8364 1.1 mrg if (expr->representation.string)
8365 1.1 mrg return false;
8366 1.1 mrg
8367 1.1 mrg switch (expr->ts.type)
8368 1.1 mrg {
8369 1.1 mrg case BT_INTEGER:
8370 1.1 mrg return mpz_cmp_si (expr->value.integer, 0) == 0;
8371 1.1 mrg
8372 1.1 mrg case BT_REAL:
8373 1.1 mrg return mpfr_zero_p (expr->value.real)
8374 1.1 mrg && MPFR_SIGN (expr->value.real) >= 0;
8375 1.1 mrg
8376 1.1 mrg case BT_LOGICAL:
8377 1.1 mrg return expr->value.logical == 0;
8378 1.1 mrg
8379 1.1 mrg case BT_COMPLEX:
8380 1.1 mrg return mpfr_zero_p (mpc_realref (expr->value.complex))
8381 1.1 mrg && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
8382 1.1 mrg && mpfr_zero_p (mpc_imagref (expr->value.complex))
8383 1.1 mrg && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
8384 1.1 mrg
8385 1.1 mrg default:
8386 1.1 mrg break;
8387 1.1 mrg }
8388 1.1 mrg return false;
8389 1.1 mrg }
8390 1.1 mrg
8391 1.1 mrg
8392 1.1 mrg static void
8393 1.1 mrg gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
8394 1.1 mrg {
8395 1.1 mrg gfc_ss *ss;
8396 1.1 mrg
8397 1.1 mrg ss = se->ss;
8398 1.1 mrg gcc_assert (ss != NULL && ss != gfc_ss_terminator);
8399 1.1 mrg gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
8400 1.1 mrg
8401 1.1 mrg gfc_conv_tmp_array_ref (se);
8402 1.1 mrg }
8403 1.1 mrg
8404 1.1 mrg
8405 1.1 mrg /* Build a static initializer. EXPR is the expression for the initial value.
8406 1.1 mrg The other parameters describe the variable of the component being
8407 1.1 mrg initialized. EXPR may be null. */
8408 1.1 mrg
8409 1.1 mrg tree
8410 1.1 mrg gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
8411 1.1 mrg bool array, bool pointer, bool procptr)
8412 1.1 mrg {
8413 1.1 mrg gfc_se se;
8414 1.1 mrg
8415 1.1 mrg if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
8416 1.1 mrg && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
8417 1.1 mrg && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
8418 1.1 mrg return build_constructor (type, NULL);
8419 1.1 mrg
8420 1.1 mrg if (!(expr || pointer || procptr))
8421 1.1 mrg return NULL_TREE;
8422 1.1 mrg
8423 1.1 mrg /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
8424 1.1 mrg (these are the only two iso_c_binding derived types that can be
8425 1.1 mrg used as initialization expressions). If so, we need to modify
8426 1.1 mrg the 'expr' to be that for a (void *). */
8427 1.1 mrg if (expr != NULL && expr->ts.type == BT_DERIVED
8428 1.1 mrg && expr->ts.is_iso_c && expr->ts.u.derived)
8429 1.1 mrg {
8430 1.1 mrg if (TREE_CODE (type) == ARRAY_TYPE)
8431 1.1 mrg return build_constructor (type, NULL);
8432 1.1 mrg else if (POINTER_TYPE_P (type))
8433 1.1 mrg return build_int_cst (type, 0);
8434 1.1 mrg else
8435 1.1 mrg gcc_unreachable ();
8436 1.1 mrg }
8437 1.1 mrg
8438 1.1 mrg if (array && !procptr)
8439 1.1 mrg {
8440 1.1 mrg tree ctor;
8441 1.1 mrg /* Arrays need special handling. */
8442 1.1 mrg if (pointer)
8443 1.1 mrg ctor = gfc_build_null_descriptor (type);
8444 1.1 mrg /* Special case assigning an array to zero. */
8445 1.1 mrg else if (is_zero_initializer_p (expr))
8446 1.1 mrg ctor = build_constructor (type, NULL);
8447 1.1 mrg else
8448 1.1 mrg ctor = gfc_conv_array_initializer (type, expr);
8449 1.1 mrg TREE_STATIC (ctor) = 1;
8450 1.1 mrg return ctor;
8451 1.1 mrg }
8452 1.1 mrg else if (pointer || procptr)
8453 1.1 mrg {
8454 1.1 mrg if (ts->type == BT_CLASS && !procptr)
8455 1.1 mrg {
8456 1.1 mrg gfc_init_se (&se, NULL);
8457 1.1 mrg gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8458 1.1 mrg gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8459 1.1 mrg TREE_STATIC (se.expr) = 1;
8460 1.1 mrg return se.expr;
8461 1.1 mrg }
8462 1.1 mrg else if (!expr || expr->expr_type == EXPR_NULL)
8463 1.1 mrg return fold_convert (type, null_pointer_node);
8464 1.1 mrg else
8465 1.1 mrg {
8466 1.1 mrg gfc_init_se (&se, NULL);
8467 1.1 mrg se.want_pointer = 1;
8468 1.1 mrg gfc_conv_expr (&se, expr);
8469 1.1 mrg gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8470 1.1 mrg return se.expr;
8471 1.1 mrg }
8472 1.1 mrg }
8473 1.1 mrg else
8474 1.1 mrg {
8475 1.1 mrg switch (ts->type)
8476 1.1 mrg {
8477 1.1 mrg case_bt_struct:
8478 1.1 mrg case BT_CLASS:
8479 1.1 mrg gfc_init_se (&se, NULL);
8480 1.1 mrg if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
8481 1.1 mrg gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8482 1.1 mrg else
8483 1.1 mrg gfc_conv_structure (&se, expr, 1);
8484 1.1 mrg gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8485 1.1 mrg TREE_STATIC (se.expr) = 1;
8486 1.1 mrg return se.expr;
8487 1.1 mrg
8488 1.1 mrg case BT_CHARACTER:
8489 1.1 mrg if (expr->expr_type == EXPR_CONSTANT)
8490 1.1 mrg {
8491 1.1 mrg tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8492 1.1 mrg TREE_STATIC (ctor) = 1;
8493 1.1 mrg return ctor;
8494 1.1 mrg }
8495 1.1 mrg
8496 1.1 mrg /* Fallthrough. */
8497 1.1 mrg default:
8498 1.1 mrg gfc_init_se (&se, NULL);
8499 1.1 mrg gfc_conv_constant (&se, expr);
8500 1.1 mrg gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8501 1.1 mrg return se.expr;
8502 1.1 mrg }
8503 1.1 mrg }
8504 1.1 mrg }
8505 1.1 mrg
8506 1.1 mrg static tree
8507 1.1 mrg gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8508 1.1 mrg {
8509 1.1 mrg gfc_se rse;
8510 1.1 mrg gfc_se lse;
8511 1.1 mrg gfc_ss *rss;
8512 1.1 mrg gfc_ss *lss;
8513 1.1 mrg gfc_array_info *lss_array;
8514 1.1 mrg stmtblock_t body;
8515 1.1 mrg stmtblock_t block;
8516 1.1 mrg gfc_loopinfo loop;
8517 1.1 mrg int n;
8518 1.1 mrg tree tmp;
8519 1.1 mrg
8520 1.1 mrg gfc_start_block (&block);
8521 1.1 mrg
8522 1.1 mrg /* Initialize the scalarizer. */
8523 1.1 mrg gfc_init_loopinfo (&loop);
8524 1.1 mrg
8525 1.1 mrg gfc_init_se (&lse, NULL);
8526 1.1 mrg gfc_init_se (&rse, NULL);
8527 1.1 mrg
8528 1.1 mrg /* Walk the rhs. */
8529 1.1 mrg rss = gfc_walk_expr (expr);
8530 1.1 mrg if (rss == gfc_ss_terminator)
8531 1.1 mrg /* The rhs is scalar. Add a ss for the expression. */
8532 1.1 mrg rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
8533 1.1 mrg
8534 1.1 mrg /* Create a SS for the destination. */
8535 1.1 mrg lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8536 1.1 mrg GFC_SS_COMPONENT);
8537 1.1 mrg lss_array = &lss->info->data.array;
8538 1.1 mrg lss_array->shape = gfc_get_shape (cm->as->rank);
8539 1.1 mrg lss_array->descriptor = dest;
8540 1.1 mrg lss_array->data = gfc_conv_array_data (dest);
8541 1.1 mrg lss_array->offset = gfc_conv_array_offset (dest);
8542 1.1 mrg for (n = 0; n < cm->as->rank; n++)
8543 1.1 mrg {
8544 1.1 mrg lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8545 1.1 mrg lss_array->stride[n] = gfc_index_one_node;
8546 1.1 mrg
8547 1.1 mrg mpz_init (lss_array->shape[n]);
8548 1.1 mrg mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
8549 1.1 mrg cm->as->lower[n]->value.integer);
8550 1.1 mrg mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
8551 1.1 mrg }
8552 1.1 mrg
8553 1.1 mrg /* Associate the SS with the loop. */
8554 1.1 mrg gfc_add_ss_to_loop (&loop, lss);
8555 1.1 mrg gfc_add_ss_to_loop (&loop, rss);
8556 1.1 mrg
8557 1.1 mrg /* Calculate the bounds of the scalarization. */
8558 1.1 mrg gfc_conv_ss_startstride (&loop);
8559 1.1 mrg
8560 1.1 mrg /* Setup the scalarizing loops. */
8561 1.1 mrg gfc_conv_loop_setup (&loop, &expr->where);
8562 1.1 mrg
8563 1.1 mrg /* Setup the gfc_se structures. */
8564 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop);
8565 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop);
8566 1.1 mrg
8567 1.1 mrg rse.ss = rss;
8568 1.1 mrg gfc_mark_ss_chain_used (rss, 1);
8569 1.1 mrg lse.ss = lss;
8570 1.1 mrg gfc_mark_ss_chain_used (lss, 1);
8571 1.1 mrg
8572 1.1 mrg /* Start the scalarized loop body. */
8573 1.1 mrg gfc_start_scalarized_body (&loop, &body);
8574 1.1 mrg
8575 1.1 mrg gfc_conv_tmp_array_ref (&lse);
8576 1.1 mrg if (cm->ts.type == BT_CHARACTER)
8577 1.1 mrg lse.string_length = cm->ts.u.cl->backend_decl;
8578 1.1 mrg
8579 1.1 mrg gfc_conv_expr (&rse, expr);
8580 1.1 mrg
8581 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
8582 1.1 mrg gfc_add_expr_to_block (&body, tmp);
8583 1.1 mrg
8584 1.1 mrg gcc_assert (rse.ss == gfc_ss_terminator);
8585 1.1 mrg
8586 1.1 mrg /* Generate the copying loops. */
8587 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body);
8588 1.1 mrg
8589 1.1 mrg /* Wrap the whole thing up. */
8590 1.1 mrg gfc_add_block_to_block (&block, &loop.pre);
8591 1.1 mrg gfc_add_block_to_block (&block, &loop.post);
8592 1.1 mrg
8593 1.1 mrg gcc_assert (lss_array->shape != NULL);
8594 1.1 mrg gfc_free_shape (&lss_array->shape, cm->as->rank);
8595 1.1 mrg gfc_cleanup_loop (&loop);
8596 1.1 mrg
8597 1.1 mrg return gfc_finish_block (&block);
8598 1.1 mrg }
8599 1.1 mrg
8600 1.1 mrg
8601 1.1 mrg static tree
8602 1.1 mrg gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8603 1.1 mrg gfc_expr * expr)
8604 1.1 mrg {
8605 1.1 mrg gfc_se se;
8606 1.1 mrg stmtblock_t block;
8607 1.1 mrg tree offset;
8608 1.1 mrg int n;
8609 1.1 mrg tree tmp;
8610 1.1 mrg tree tmp2;
8611 1.1 mrg gfc_array_spec *as;
8612 1.1 mrg gfc_expr *arg = NULL;
8613 1.1 mrg
8614 1.1 mrg gfc_start_block (&block);
8615 1.1 mrg gfc_init_se (&se, NULL);
8616 1.1 mrg
8617 1.1 mrg /* Get the descriptor for the expressions. */
8618 1.1 mrg se.want_pointer = 0;
8619 1.1 mrg gfc_conv_expr_descriptor (&se, expr);
8620 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
8621 1.1 mrg gfc_add_modify (&block, dest, se.expr);
8622 1.1 mrg
8623 1.1 mrg /* Deal with arrays of derived types with allocatable components. */
8624 1.1 mrg if (gfc_bt_struct (cm->ts.type)
8625 1.1 mrg && cm->ts.u.derived->attr.alloc_comp)
8626 1.1 mrg // TODO: Fix caf_mode
8627 1.1 mrg tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8628 1.1 mrg se.expr, dest,
8629 1.1 mrg cm->as->rank, 0);
8630 1.1 mrg else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8631 1.1 mrg && CLASS_DATA(cm)->attr.allocatable)
8632 1.1 mrg {
8633 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp)
8634 1.1 mrg // TODO: Fix caf_mode
8635 1.1 mrg tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8636 1.1 mrg se.expr, dest,
8637 1.1 mrg expr->rank, 0);
8638 1.1 mrg else
8639 1.1 mrg {
8640 1.1 mrg tmp = TREE_TYPE (dest);
8641 1.1 mrg tmp = gfc_duplicate_allocatable (dest, se.expr,
8642 1.1 mrg tmp, expr->rank, NULL_TREE);
8643 1.1 mrg }
8644 1.1 mrg }
8645 1.1 mrg else
8646 1.1 mrg tmp = gfc_duplicate_allocatable (dest, se.expr,
8647 1.1 mrg TREE_TYPE(cm->backend_decl),
8648 1.1 mrg cm->as->rank, NULL_TREE);
8649 1.1 mrg
8650 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8651 1.1 mrg gfc_add_block_to_block (&block, &se.post);
8652 1.1 mrg
8653 1.1 mrg if (expr->expr_type != EXPR_VARIABLE)
8654 1.1 mrg gfc_conv_descriptor_data_set (&block, se.expr,
8655 1.1 mrg null_pointer_node);
8656 1.1 mrg
8657 1.1 mrg /* We need to know if the argument of a conversion function is a
8658 1.1 mrg variable, so that the correct lower bound can be used. */
8659 1.1 mrg if (expr->expr_type == EXPR_FUNCTION
8660 1.1 mrg && expr->value.function.isym
8661 1.1 mrg && expr->value.function.isym->conversion
8662 1.1 mrg && expr->value.function.actual->expr
8663 1.1 mrg && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8664 1.1 mrg arg = expr->value.function.actual->expr;
8665 1.1 mrg
8666 1.1 mrg /* Obtain the array spec of full array references. */
8667 1.1 mrg if (arg)
8668 1.1 mrg as = gfc_get_full_arrayspec_from_expr (arg);
8669 1.1 mrg else
8670 1.1 mrg as = gfc_get_full_arrayspec_from_expr (expr);
8671 1.1 mrg
8672 1.1 mrg /* Shift the lbound and ubound of temporaries to being unity,
8673 1.1 mrg rather than zero, based. Always calculate the offset. */
8674 1.1 mrg offset = gfc_conv_descriptor_offset_get (dest);
8675 1.1 mrg gfc_add_modify (&block, offset, gfc_index_zero_node);
8676 1.1 mrg tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8677 1.1 mrg
8678 1.1 mrg for (n = 0; n < expr->rank; n++)
8679 1.1 mrg {
8680 1.1 mrg tree span;
8681 1.1 mrg tree lbound;
8682 1.1 mrg
8683 1.1 mrg /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8684 1.1 mrg TODO It looks as if gfc_conv_expr_descriptor should return
8685 1.1 mrg the correct bounds and that the following should not be
8686 1.1 mrg necessary. This would simplify gfc_conv_intrinsic_bound
8687 1.1 mrg as well. */
8688 1.1 mrg if (as && as->lower[n])
8689 1.1 mrg {
8690 1.1 mrg gfc_se lbse;
8691 1.1 mrg gfc_init_se (&lbse, NULL);
8692 1.1 mrg gfc_conv_expr (&lbse, as->lower[n]);
8693 1.1 mrg gfc_add_block_to_block (&block, &lbse.pre);
8694 1.1 mrg lbound = gfc_evaluate_now (lbse.expr, &block);
8695 1.1 mrg }
8696 1.1 mrg else if (as && arg)
8697 1.1 mrg {
8698 1.1 mrg tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8699 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (tmp,
8700 1.1 mrg gfc_rank_cst[n]);
8701 1.1 mrg }
8702 1.1 mrg else if (as)
8703 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (dest,
8704 1.1 mrg gfc_rank_cst[n]);
8705 1.1 mrg else
8706 1.1 mrg lbound = gfc_index_one_node;
8707 1.1 mrg
8708 1.1 mrg lbound = fold_convert (gfc_array_index_type, lbound);
8709 1.1 mrg
8710 1.1 mrg /* Shift the bounds and set the offset accordingly. */
8711 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
8712 1.1 mrg span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8713 1.1 mrg tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8714 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8715 1.1 mrg span, lbound);
8716 1.1 mrg gfc_conv_descriptor_ubound_set (&block, dest,
8717 1.1 mrg gfc_rank_cst[n], tmp);
8718 1.1 mrg gfc_conv_descriptor_lbound_set (&block, dest,
8719 1.1 mrg gfc_rank_cst[n], lbound);
8720 1.1 mrg
8721 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8722 1.1 mrg gfc_conv_descriptor_lbound_get (dest,
8723 1.1 mrg gfc_rank_cst[n]),
8724 1.1 mrg gfc_conv_descriptor_stride_get (dest,
8725 1.1 mrg gfc_rank_cst[n]));
8726 1.1 mrg gfc_add_modify (&block, tmp2, tmp);
8727 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8728 1.1 mrg offset, tmp2);
8729 1.1 mrg gfc_conv_descriptor_offset_set (&block, dest, tmp);
8730 1.1 mrg }
8731 1.1 mrg
8732 1.1 mrg if (arg)
8733 1.1 mrg {
8734 1.1 mrg /* If a conversion expression has a null data pointer
8735 1.1 mrg argument, nullify the allocatable component. */
8736 1.1 mrg tree non_null_expr;
8737 1.1 mrg tree null_expr;
8738 1.1 mrg
8739 1.1 mrg if (arg->symtree->n.sym->attr.allocatable
8740 1.1 mrg || arg->symtree->n.sym->attr.pointer)
8741 1.1 mrg {
8742 1.1 mrg non_null_expr = gfc_finish_block (&block);
8743 1.1 mrg gfc_start_block (&block);
8744 1.1 mrg gfc_conv_descriptor_data_set (&block, dest,
8745 1.1 mrg null_pointer_node);
8746 1.1 mrg null_expr = gfc_finish_block (&block);
8747 1.1 mrg tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
8748 1.1 mrg tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
8749 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node));
8750 1.1 mrg return build3_v (COND_EXPR, tmp,
8751 1.1 mrg null_expr, non_null_expr);
8752 1.1 mrg }
8753 1.1 mrg }
8754 1.1 mrg
8755 1.1 mrg return gfc_finish_block (&block);
8756 1.1 mrg }
8757 1.1 mrg
8758 1.1 mrg
8759 1.1 mrg /* Allocate or reallocate scalar component, as necessary. */
8760 1.1 mrg
8761 1.1 mrg static void
8762 1.1 mrg alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
8763 1.1 mrg tree comp,
8764 1.1 mrg gfc_component *cm,
8765 1.1 mrg gfc_expr *expr2,
8766 1.1 mrg gfc_symbol *sym)
8767 1.1 mrg {
8768 1.1 mrg tree tmp;
8769 1.1 mrg tree ptr;
8770 1.1 mrg tree size;
8771 1.1 mrg tree size_in_bytes;
8772 1.1 mrg tree lhs_cl_size = NULL_TREE;
8773 1.1 mrg
8774 1.1 mrg if (!comp)
8775 1.1 mrg return;
8776 1.1 mrg
8777 1.1 mrg if (!expr2 || expr2->rank)
8778 1.1 mrg return;
8779 1.1 mrg
8780 1.1 mrg realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8781 1.1 mrg
8782 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8783 1.1 mrg {
8784 1.1 mrg char name[GFC_MAX_SYMBOL_LEN+9];
8785 1.1 mrg gfc_component *strlen;
8786 1.1 mrg /* Use the rhs string length and the lhs element size. */
8787 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER);
8788 1.1 mrg if (!expr2->ts.u.cl->backend_decl)
8789 1.1 mrg {
8790 1.1 mrg gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
8791 1.1 mrg gcc_assert (expr2->ts.u.cl->backend_decl);
8792 1.1 mrg }
8793 1.1 mrg
8794 1.1 mrg size = expr2->ts.u.cl->backend_decl;
8795 1.1 mrg
8796 1.1 mrg /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8797 1.1 mrg component. */
8798 1.1 mrg sprintf (name, "_%s_length", cm->name);
8799 1.1 mrg strlen = gfc_find_component (sym, name, true, true, NULL);
8800 1.1 mrg lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8801 1.1 mrg gfc_charlen_type_node,
8802 1.1 mrg TREE_OPERAND (comp, 0),
8803 1.1 mrg strlen->backend_decl, NULL_TREE);
8804 1.1 mrg
8805 1.1 mrg tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8806 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp);
8807 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8808 1.1 mrg TREE_TYPE (tmp), tmp,
8809 1.1 mrg fold_convert (TREE_TYPE (tmp), size));
8810 1.1 mrg }
8811 1.1 mrg else if (cm->ts.type == BT_CLASS)
8812 1.1 mrg {
8813 1.1 mrg gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
8814 1.1 mrg if (expr2->ts.type == BT_DERIVED)
8815 1.1 mrg {
8816 1.1 mrg tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
8817 1.1 mrg size = TYPE_SIZE_UNIT (tmp);
8818 1.1 mrg }
8819 1.1 mrg else
8820 1.1 mrg {
8821 1.1 mrg gfc_expr *e2vtab;
8822 1.1 mrg gfc_se se;
8823 1.1 mrg e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
8824 1.1 mrg gfc_add_vptr_component (e2vtab);
8825 1.1 mrg gfc_add_size_component (e2vtab);
8826 1.1 mrg gfc_init_se (&se, NULL);
8827 1.1 mrg gfc_conv_expr (&se, e2vtab);
8828 1.1 mrg gfc_add_block_to_block (block, &se.pre);
8829 1.1 mrg size = fold_convert (size_type_node, se.expr);
8830 1.1 mrg gfc_free_expr (e2vtab);
8831 1.1 mrg }
8832 1.1 mrg size_in_bytes = size;
8833 1.1 mrg }
8834 1.1 mrg else
8835 1.1 mrg {
8836 1.1 mrg /* Otherwise use the length in bytes of the rhs. */
8837 1.1 mrg size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
8838 1.1 mrg size_in_bytes = size;
8839 1.1 mrg }
8840 1.1 mrg
8841 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
8842 1.1 mrg size_in_bytes, size_one_node);
8843 1.1 mrg
8844 1.1 mrg if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
8845 1.1 mrg {
8846 1.1 mrg tmp = build_call_expr_loc (input_location,
8847 1.1 mrg builtin_decl_explicit (BUILT_IN_CALLOC),
8848 1.1 mrg 2, build_one_cst (size_type_node),
8849 1.1 mrg size_in_bytes);
8850 1.1 mrg tmp = fold_convert (TREE_TYPE (comp), tmp);
8851 1.1 mrg gfc_add_modify (block, comp, tmp);
8852 1.1 mrg }
8853 1.1 mrg else
8854 1.1 mrg {
8855 1.1 mrg tmp = build_call_expr_loc (input_location,
8856 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC),
8857 1.1 mrg 1, size_in_bytes);
8858 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
8859 1.1 mrg ptr = gfc_class_data_get (comp);
8860 1.1 mrg else
8861 1.1 mrg ptr = comp;
8862 1.1 mrg tmp = fold_convert (TREE_TYPE (ptr), tmp);
8863 1.1 mrg gfc_add_modify (block, ptr, tmp);
8864 1.1 mrg }
8865 1.1 mrg
8866 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8867 1.1 mrg /* Update the lhs character length. */
8868 1.1 mrg gfc_add_modify (block, lhs_cl_size,
8869 1.1 mrg fold_convert (TREE_TYPE (lhs_cl_size), size));
8870 1.1 mrg }
8871 1.1 mrg
8872 1.1 mrg
8873 1.1 mrg /* Assign a single component of a derived type constructor. */
8874 1.1 mrg
8875 1.1 mrg static tree
8876 1.1 mrg gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
8877 1.1 mrg gfc_symbol *sym, bool init)
8878 1.1 mrg {
8879 1.1 mrg gfc_se se;
8880 1.1 mrg gfc_se lse;
8881 1.1 mrg stmtblock_t block;
8882 1.1 mrg tree tmp;
8883 1.1 mrg tree vtab;
8884 1.1 mrg
8885 1.1 mrg gfc_start_block (&block);
8886 1.1 mrg
8887 1.1 mrg if (cm->attr.pointer || cm->attr.proc_pointer)
8888 1.1 mrg {
8889 1.1 mrg /* Only care about pointers here, not about allocatables. */
8890 1.1 mrg gfc_init_se (&se, NULL);
8891 1.1 mrg /* Pointer component. */
8892 1.1 mrg if ((cm->attr.dimension || cm->attr.codimension)
8893 1.1 mrg && !cm->attr.proc_pointer)
8894 1.1 mrg {
8895 1.1 mrg /* Array pointer. */
8896 1.1 mrg if (expr->expr_type == EXPR_NULL)
8897 1.1 mrg gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8898 1.1 mrg else
8899 1.1 mrg {
8900 1.1 mrg se.direct_byref = 1;
8901 1.1 mrg se.expr = dest;
8902 1.1 mrg gfc_conv_expr_descriptor (&se, expr);
8903 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
8904 1.1 mrg gfc_add_block_to_block (&block, &se.post);
8905 1.1 mrg }
8906 1.1 mrg }
8907 1.1 mrg else
8908 1.1 mrg {
8909 1.1 mrg /* Scalar pointers. */
8910 1.1 mrg se.want_pointer = 1;
8911 1.1 mrg gfc_conv_expr (&se, expr);
8912 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
8913 1.1 mrg
8914 1.1 mrg if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8915 1.1 mrg && expr->symtree->n.sym->attr.dummy)
8916 1.1 mrg se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8917 1.1 mrg
8918 1.1 mrg gfc_add_modify (&block, dest,
8919 1.1 mrg fold_convert (TREE_TYPE (dest), se.expr));
8920 1.1 mrg gfc_add_block_to_block (&block, &se.post);
8921 1.1 mrg }
8922 1.1 mrg }
8923 1.1 mrg else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
8924 1.1 mrg {
8925 1.1 mrg /* NULL initialization for CLASS components. */
8926 1.1 mrg tmp = gfc_trans_structure_assign (dest,
8927 1.1 mrg gfc_class_initializer (&cm->ts, expr),
8928 1.1 mrg false);
8929 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8930 1.1 mrg }
8931 1.1 mrg else if ((cm->attr.dimension || cm->attr.codimension)
8932 1.1 mrg && !cm->attr.proc_pointer)
8933 1.1 mrg {
8934 1.1 mrg if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8935 1.1 mrg gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8936 1.1 mrg else if (cm->attr.allocatable || cm->attr.pdt_array)
8937 1.1 mrg {
8938 1.1 mrg tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
8939 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8940 1.1 mrg }
8941 1.1 mrg else
8942 1.1 mrg {
8943 1.1 mrg tmp = gfc_trans_subarray_assign (dest, cm, expr);
8944 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8945 1.1 mrg }
8946 1.1 mrg }
8947 1.1 mrg else if (cm->ts.type == BT_CLASS
8948 1.1 mrg && CLASS_DATA (cm)->attr.dimension
8949 1.1 mrg && CLASS_DATA (cm)->attr.allocatable
8950 1.1 mrg && expr->ts.type == BT_DERIVED)
8951 1.1 mrg {
8952 1.1 mrg vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8953 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8954 1.1 mrg tmp = gfc_class_vptr_get (dest);
8955 1.1 mrg gfc_add_modify (&block, tmp,
8956 1.1 mrg fold_convert (TREE_TYPE (tmp), vtab));
8957 1.1 mrg tmp = gfc_class_data_get (dest);
8958 1.1 mrg tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
8959 1.1 mrg gfc_add_expr_to_block (&block, tmp);
8960 1.1 mrg }
8961 1.1 mrg else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8962 1.1 mrg {
8963 1.1 mrg /* NULL initialization for allocatable components. */
8964 1.1 mrg gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
8965 1.1 mrg null_pointer_node));
8966 1.1 mrg }
8967 1.1 mrg else if (init && (cm->attr.allocatable
8968 1.1 mrg || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
8969 1.1 mrg && expr->ts.type != BT_CLASS)))
8970 1.1 mrg {
8971 1.1 mrg /* Take care about non-array allocatable components here. The alloc_*
8972 1.1 mrg routine below is motivated by the alloc_scalar_allocatable_for_
8973 1.1 mrg assignment() routine, but with the realloc portions removed and
8974 1.1 mrg different input. */
8975 1.1 mrg alloc_scalar_allocatable_for_subcomponent_assignment (&block,
8976 1.1 mrg dest,
8977 1.1 mrg cm,
8978 1.1 mrg expr,
8979 1.1 mrg sym);
8980 1.1 mrg /* The remainder of these instructions follow the if (cm->attr.pointer)
8981 1.1 mrg if (!cm->attr.dimension) part above. */
8982 1.1 mrg gfc_init_se (&se, NULL);
8983 1.1 mrg gfc_conv_expr (&se, expr);
8984 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
8985 1.1 mrg
8986 1.1 mrg if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8987 1.1 mrg && expr->symtree->n.sym->attr.dummy)
8988 1.1 mrg se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8989 1.1 mrg
8990 1.1 mrg if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
8991 1.1 mrg {
8992 1.1 mrg tmp = gfc_class_data_get (dest);
8993 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
8994 1.1 mrg vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8995 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8996 1.1 mrg gfc_add_modify (&block, gfc_class_vptr_get (dest),
8997 1.1 mrg fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
8998 1.1 mrg }
8999 1.1 mrg else
9000 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, dest);
9001 1.1 mrg
9002 1.1 mrg /* For deferred strings insert a memcpy. */
9003 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
9004 1.1 mrg {
9005 1.1 mrg tree size;
9006 1.1 mrg gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
9007 1.1 mrg size = size_of_string_in_bytes (cm->ts.kind, se.string_length
9008 1.1 mrg ? se.string_length
9009 1.1 mrg : expr->ts.u.cl->backend_decl);
9010 1.1 mrg tmp = gfc_build_memcpy_call (tmp, se.expr, size);
9011 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9012 1.1 mrg }
9013 1.1 mrg else
9014 1.1 mrg gfc_add_modify (&block, tmp,
9015 1.1 mrg fold_convert (TREE_TYPE (tmp), se.expr));
9016 1.1 mrg gfc_add_block_to_block (&block, &se.post);
9017 1.1 mrg }
9018 1.1 mrg else if (expr->ts.type == BT_UNION)
9019 1.1 mrg {
9020 1.1 mrg tree tmp;
9021 1.1 mrg gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
9022 1.1 mrg /* We mark that the entire union should be initialized with a contrived
9023 1.1 mrg EXPR_NULL expression at the beginning. */
9024 1.1 mrg if (c != NULL && c->n.component == NULL
9025 1.1 mrg && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
9026 1.1 mrg {
9027 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9028 1.1 mrg dest, build_constructor (TREE_TYPE (dest), NULL));
9029 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9030 1.1 mrg c = gfc_constructor_next (c);
9031 1.1 mrg }
9032 1.1 mrg /* The following constructor expression, if any, represents a specific
9033 1.1 mrg map intializer, as given by the user. */
9034 1.1 mrg if (c != NULL && c->expr != NULL)
9035 1.1 mrg {
9036 1.1 mrg gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9037 1.1 mrg tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9038 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9039 1.1 mrg }
9040 1.1 mrg }
9041 1.1 mrg else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
9042 1.1 mrg {
9043 1.1 mrg if (expr->expr_type != EXPR_STRUCTURE)
9044 1.1 mrg {
9045 1.1 mrg tree dealloc = NULL_TREE;
9046 1.1 mrg gfc_init_se (&se, NULL);
9047 1.1 mrg gfc_conv_expr (&se, expr);
9048 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
9049 1.1 mrg /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
9050 1.1 mrg expression in a temporary variable and deallocate the allocatable
9051 1.1 mrg components. Then we can the copy the expression to the result. */
9052 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp
9053 1.1 mrg && expr->expr_type != EXPR_VARIABLE)
9054 1.1 mrg {
9055 1.1 mrg se.expr = gfc_evaluate_now (se.expr, &block);
9056 1.1 mrg dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
9057 1.1 mrg expr->rank);
9058 1.1 mrg }
9059 1.1 mrg gfc_add_modify (&block, dest,
9060 1.1 mrg fold_convert (TREE_TYPE (dest), se.expr));
9061 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp
9062 1.1 mrg && expr->expr_type != EXPR_NULL)
9063 1.1 mrg {
9064 1.1 mrg // TODO: Fix caf_mode
9065 1.1 mrg tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
9066 1.1 mrg dest, expr->rank, 0);
9067 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9068 1.1 mrg if (dealloc != NULL_TREE)
9069 1.1 mrg gfc_add_expr_to_block (&block, dealloc);
9070 1.1 mrg }
9071 1.1 mrg gfc_add_block_to_block (&block, &se.post);
9072 1.1 mrg }
9073 1.1 mrg else
9074 1.1 mrg {
9075 1.1 mrg /* Nested constructors. */
9076 1.1 mrg tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9077 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9078 1.1 mrg }
9079 1.1 mrg }
9080 1.1 mrg else if (gfc_deferred_strlen (cm, &tmp))
9081 1.1 mrg {
9082 1.1 mrg tree strlen;
9083 1.1 mrg strlen = tmp;
9084 1.1 mrg gcc_assert (strlen);
9085 1.1 mrg strlen = fold_build3_loc (input_location, COMPONENT_REF,
9086 1.1 mrg TREE_TYPE (strlen),
9087 1.1 mrg TREE_OPERAND (dest, 0),
9088 1.1 mrg strlen, NULL_TREE);
9089 1.1 mrg
9090 1.1 mrg if (expr->expr_type == EXPR_NULL)
9091 1.1 mrg {
9092 1.1 mrg tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
9093 1.1 mrg gfc_add_modify (&block, dest, tmp);
9094 1.1 mrg tmp = build_int_cst (TREE_TYPE (strlen), 0);
9095 1.1 mrg gfc_add_modify (&block, strlen, tmp);
9096 1.1 mrg }
9097 1.1 mrg else
9098 1.1 mrg {
9099 1.1 mrg tree size;
9100 1.1 mrg gfc_init_se (&se, NULL);
9101 1.1 mrg gfc_conv_expr (&se, expr);
9102 1.1 mrg size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
9103 1.1 mrg tmp = build_call_expr_loc (input_location,
9104 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC),
9105 1.1 mrg 1, size);
9106 1.1 mrg gfc_add_modify (&block, dest,
9107 1.1 mrg fold_convert (TREE_TYPE (dest), tmp));
9108 1.1 mrg gfc_add_modify (&block, strlen,
9109 1.1 mrg fold_convert (TREE_TYPE (strlen), se.string_length));
9110 1.1 mrg tmp = gfc_build_memcpy_call (dest, se.expr, size);
9111 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9112 1.1 mrg }
9113 1.1 mrg }
9114 1.1 mrg else if (!cm->attr.artificial)
9115 1.1 mrg {
9116 1.1 mrg /* Scalar component (excluding deferred parameters). */
9117 1.1 mrg gfc_init_se (&se, NULL);
9118 1.1 mrg gfc_init_se (&lse, NULL);
9119 1.1 mrg
9120 1.1 mrg gfc_conv_expr (&se, expr);
9121 1.1 mrg if (cm->ts.type == BT_CHARACTER)
9122 1.1 mrg lse.string_length = cm->ts.u.cl->backend_decl;
9123 1.1 mrg lse.expr = dest;
9124 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
9125 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9126 1.1 mrg }
9127 1.1 mrg return gfc_finish_block (&block);
9128 1.1 mrg }
9129 1.1 mrg
9130 1.1 mrg /* Assign a derived type constructor to a variable. */
9131 1.1 mrg
9132 1.1 mrg tree
9133 1.1 mrg gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
9134 1.1 mrg {
9135 1.1 mrg gfc_constructor *c;
9136 1.1 mrg gfc_component *cm;
9137 1.1 mrg stmtblock_t block;
9138 1.1 mrg tree field;
9139 1.1 mrg tree tmp;
9140 1.1 mrg gfc_se se;
9141 1.1 mrg
9142 1.1 mrg gfc_start_block (&block);
9143 1.1 mrg
9144 1.1 mrg if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
9145 1.1 mrg && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
9146 1.1 mrg || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
9147 1.1 mrg {
9148 1.1 mrg gfc_se lse;
9149 1.1 mrg
9150 1.1 mrg gfc_init_se (&se, NULL);
9151 1.1 mrg gfc_init_se (&lse, NULL);
9152 1.1 mrg gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
9153 1.1 mrg lse.expr = dest;
9154 1.1 mrg gfc_add_modify (&block, lse.expr,
9155 1.1 mrg fold_convert (TREE_TYPE (lse.expr), se.expr));
9156 1.1 mrg
9157 1.1 mrg return gfc_finish_block (&block);
9158 1.1 mrg }
9159 1.1 mrg
9160 1.1 mrg /* Make sure that the derived type has been completely built. */
9161 1.1 mrg if (!expr->ts.u.derived->backend_decl
9162 1.1 mrg || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
9163 1.1 mrg {
9164 1.1 mrg tmp = gfc_typenode_for_spec (&expr->ts);
9165 1.1 mrg gcc_assert (tmp);
9166 1.1 mrg }
9167 1.1 mrg
9168 1.1 mrg cm = expr->ts.u.derived->components;
9169 1.1 mrg
9170 1.1 mrg
9171 1.1 mrg if (coarray)
9172 1.1 mrg gfc_init_se (&se, NULL);
9173 1.1 mrg
9174 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor);
9175 1.1 mrg c; c = gfc_constructor_next (c), cm = cm->next)
9176 1.1 mrg {
9177 1.1 mrg /* Skip absent members in default initializers. */
9178 1.1 mrg if (!c->expr && !cm->attr.allocatable)
9179 1.1 mrg continue;
9180 1.1 mrg
9181 1.1 mrg /* Register the component with the caf-lib before it is initialized.
9182 1.1 mrg Register only allocatable components, that are not coarray'ed
9183 1.1 mrg components (%comp[*]). Only register when the constructor is not the
9184 1.1 mrg null-expression. */
9185 1.1 mrg if (coarray && !cm->attr.codimension
9186 1.1 mrg && (cm->attr.allocatable || cm->attr.pointer)
9187 1.1 mrg && (!c->expr || c->expr->expr_type == EXPR_NULL))
9188 1.1 mrg {
9189 1.1 mrg tree token, desc, size;
9190 1.1 mrg bool is_array = cm->ts.type == BT_CLASS
9191 1.1 mrg ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
9192 1.1 mrg
9193 1.1 mrg field = cm->backend_decl;
9194 1.1 mrg field = fold_build3_loc (input_location, COMPONENT_REF,
9195 1.1 mrg TREE_TYPE (field), dest, field, NULL_TREE);
9196 1.1 mrg if (cm->ts.type == BT_CLASS)
9197 1.1 mrg field = gfc_class_data_get (field);
9198 1.1 mrg
9199 1.1 mrg token = is_array ? gfc_conv_descriptor_token (field)
9200 1.1 mrg : fold_build3_loc (input_location, COMPONENT_REF,
9201 1.1 mrg TREE_TYPE (cm->caf_token), dest,
9202 1.1 mrg cm->caf_token, NULL_TREE);
9203 1.1 mrg
9204 1.1 mrg if (is_array)
9205 1.1 mrg {
9206 1.1 mrg /* The _caf_register routine looks at the rank of the array
9207 1.1 mrg descriptor to decide whether the data registered is an array
9208 1.1 mrg or not. */
9209 1.1 mrg int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
9210 1.1 mrg : cm->as->rank;
9211 1.1 mrg /* When the rank is not known just set a positive rank, which
9212 1.1 mrg suffices to recognize the data as array. */
9213 1.1 mrg if (rank < 0)
9214 1.1 mrg rank = 1;
9215 1.1 mrg size = build_zero_cst (size_type_node);
9216 1.1 mrg desc = field;
9217 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
9218 1.1 mrg build_int_cst (signed_char_type_node, rank));
9219 1.1 mrg }
9220 1.1 mrg else
9221 1.1 mrg {
9222 1.1 mrg desc = gfc_conv_scalar_to_descriptor (&se, field,
9223 1.1 mrg cm->ts.type == BT_CLASS
9224 1.1 mrg ? CLASS_DATA (cm)->attr
9225 1.1 mrg : cm->attr);
9226 1.1 mrg size = TYPE_SIZE_UNIT (TREE_TYPE (field));
9227 1.1 mrg }
9228 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
9229 1.1 mrg tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
9230 1.1 mrg 7, size, build_int_cst (
9231 1.1 mrg integer_type_node,
9232 1.1 mrg GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
9233 1.1 mrg gfc_build_addr_expr (pvoid_type_node,
9234 1.1 mrg token),
9235 1.1 mrg gfc_build_addr_expr (NULL_TREE, desc),
9236 1.1 mrg null_pointer_node, null_pointer_node,
9237 1.1 mrg integer_zero_node);
9238 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9239 1.1 mrg }
9240 1.1 mrg field = cm->backend_decl;
9241 1.1 mrg gcc_assert(field);
9242 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
9243 1.1 mrg dest, field, NULL_TREE);
9244 1.1 mrg if (!c->expr)
9245 1.1 mrg {
9246 1.1 mrg gfc_expr *e = gfc_get_null_expr (NULL);
9247 1.1 mrg tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
9248 1.1 mrg init);
9249 1.1 mrg gfc_free_expr (e);
9250 1.1 mrg }
9251 1.1 mrg else
9252 1.1 mrg tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
9253 1.1 mrg expr->ts.u.derived, init);
9254 1.1 mrg gfc_add_expr_to_block (&block, tmp);
9255 1.1 mrg }
9256 1.1 mrg return gfc_finish_block (&block);
9257 1.1 mrg }
9258 1.1 mrg
9259 1.1 mrg static void
9260 1.1 mrg gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
9261 1.1 mrg gfc_component *un, gfc_expr *init)
9262 1.1 mrg {
9263 1.1 mrg gfc_constructor *ctor;
9264 1.1 mrg
9265 1.1 mrg if (un->ts.type != BT_UNION || un == NULL || init == NULL)
9266 1.1 mrg return;
9267 1.1 mrg
9268 1.1 mrg ctor = gfc_constructor_first (init->value.constructor);
9269 1.1 mrg
9270 1.1 mrg if (ctor == NULL || ctor->expr == NULL)
9271 1.1 mrg return;
9272 1.1 mrg
9273 1.1 mrg gcc_assert (init->expr_type == EXPR_STRUCTURE);
9274 1.1 mrg
9275 1.1 mrg /* If we have an 'initialize all' constructor, do it first. */
9276 1.1 mrg if (ctor->expr->expr_type == EXPR_NULL)
9277 1.1 mrg {
9278 1.1 mrg tree union_type = TREE_TYPE (un->backend_decl);
9279 1.1 mrg tree val = build_constructor (union_type, NULL);
9280 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9281 1.1 mrg ctor = gfc_constructor_next (ctor);
9282 1.1 mrg }
9283 1.1 mrg
9284 1.1 mrg /* Add the map initializer on top. */
9285 1.1 mrg if (ctor != NULL && ctor->expr != NULL)
9286 1.1 mrg {
9287 1.1 mrg gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
9288 1.1 mrg tree val = gfc_conv_initializer (ctor->expr, &un->ts,
9289 1.1 mrg TREE_TYPE (un->backend_decl),
9290 1.1 mrg un->attr.dimension, un->attr.pointer,
9291 1.1 mrg un->attr.proc_pointer);
9292 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9293 1.1 mrg }
9294 1.1 mrg }
9295 1.1 mrg
9296 1.1 mrg /* Build an expression for a constructor. If init is nonzero then
9297 1.1 mrg this is part of a static variable initializer. */
9298 1.1 mrg
9299 1.1 mrg void
9300 1.1 mrg gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
9301 1.1 mrg {
9302 1.1 mrg gfc_constructor *c;
9303 1.1 mrg gfc_component *cm;
9304 1.1 mrg tree val;
9305 1.1 mrg tree type;
9306 1.1 mrg tree tmp;
9307 1.1 mrg vec<constructor_elt, va_gc> *v = NULL;
9308 1.1 mrg
9309 1.1 mrg gcc_assert (se->ss == NULL);
9310 1.1 mrg gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9311 1.1 mrg type = gfc_typenode_for_spec (&expr->ts);
9312 1.1 mrg
9313 1.1 mrg if (!init)
9314 1.1 mrg {
9315 1.1 mrg /* Create a temporary variable and fill it in. */
9316 1.1 mrg se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9317 1.1 mrg /* The symtree in expr is NULL, if the code to generate is for
9318 1.1 mrg initializing the static members only. */
9319 1.1 mrg tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
9320 1.1 mrg se->want_coarray);
9321 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp);
9322 1.1 mrg return;
9323 1.1 mrg }
9324 1.1 mrg
9325 1.1 mrg cm = expr->ts.u.derived->components;
9326 1.1 mrg
9327 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor);
9328 1.1 mrg c && cm; c = gfc_constructor_next (c), cm = cm->next)
9329 1.1 mrg {
9330 1.1 mrg /* Skip absent members in default initializers and allocatable
9331 1.1 mrg components. Although the latter have a default initializer
9332 1.1 mrg of EXPR_NULL,... by default, the static nullify is not needed
9333 1.1 mrg since this is done every time we come into scope. */
9334 1.1 mrg if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
9335 1.1 mrg continue;
9336 1.1 mrg
9337 1.1 mrg if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
9338 1.1 mrg && strcmp (cm->name, "_extends") == 0
9339 1.1 mrg && cm->initializer->symtree)
9340 1.1 mrg {
9341 1.1 mrg tree vtab;
9342 1.1 mrg gfc_symbol *vtabs;
9343 1.1 mrg vtabs = cm->initializer->symtree->n.sym;
9344 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
9345 1.1 mrg vtab = unshare_expr_without_location (vtab);
9346 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
9347 1.1 mrg }
9348 1.1 mrg else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
9349 1.1 mrg {
9350 1.1 mrg val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
9351 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9352 1.1 mrg fold_convert (TREE_TYPE (cm->backend_decl),
9353 1.1 mrg val));
9354 1.1 mrg }
9355 1.1 mrg else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
9356 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9357 1.1 mrg fold_convert (TREE_TYPE (cm->backend_decl),
9358 1.1 mrg integer_zero_node));
9359 1.1 mrg else if (cm->ts.type == BT_UNION)
9360 1.1 mrg gfc_conv_union_initializer (v, cm, c->expr);
9361 1.1 mrg else
9362 1.1 mrg {
9363 1.1 mrg val = gfc_conv_initializer (c->expr, &cm->ts,
9364 1.1 mrg TREE_TYPE (cm->backend_decl),
9365 1.1 mrg cm->attr.dimension, cm->attr.pointer,
9366 1.1 mrg cm->attr.proc_pointer);
9367 1.1 mrg val = unshare_expr_without_location (val);
9368 1.1 mrg
9369 1.1 mrg /* Append it to the constructor list. */
9370 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
9371 1.1 mrg }
9372 1.1 mrg }
9373 1.1 mrg
9374 1.1 mrg se->expr = build_constructor (type, v);
9375 1.1 mrg if (init)
9376 1.1 mrg TREE_CONSTANT (se->expr) = 1;
9377 1.1 mrg }
9378 1.1 mrg
9379 1.1 mrg
9380 1.1 mrg /* Translate a substring expression. */
9381 1.1 mrg
9382 1.1 mrg static void
9383 1.1 mrg gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
9384 1.1 mrg {
9385 1.1 mrg gfc_ref *ref;
9386 1.1 mrg
9387 1.1 mrg ref = expr->ref;
9388 1.1 mrg
9389 1.1 mrg gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
9390 1.1 mrg
9391 1.1 mrg se->expr = gfc_build_wide_string_const (expr->ts.kind,
9392 1.1 mrg expr->value.character.length,
9393 1.1 mrg expr->value.character.string);
9394 1.1 mrg
9395 1.1 mrg se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9396 1.1 mrg TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
9397 1.1 mrg
9398 1.1 mrg if (ref)
9399 1.1 mrg gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
9400 1.1 mrg }
9401 1.1 mrg
9402 1.1 mrg
9403 1.1 mrg /* Entry point for expression translation. Evaluates a scalar quantity.
9404 1.1 mrg EXPR is the expression to be translated, and SE is the state structure if
9405 1.1 mrg called from within the scalarized. */
9406 1.1 mrg
9407 1.1 mrg void
9408 1.1 mrg gfc_conv_expr (gfc_se * se, gfc_expr * expr)
9409 1.1 mrg {
9410 1.1 mrg gfc_ss *ss;
9411 1.1 mrg
9412 1.1 mrg ss = se->ss;
9413 1.1 mrg if (ss && ss->info->expr == expr
9414 1.1 mrg && (ss->info->type == GFC_SS_SCALAR
9415 1.1 mrg || ss->info->type == GFC_SS_REFERENCE))
9416 1.1 mrg {
9417 1.1 mrg gfc_ss_info *ss_info;
9418 1.1 mrg
9419 1.1 mrg ss_info = ss->info;
9420 1.1 mrg /* Substitute a scalar expression evaluated outside the scalarization
9421 1.1 mrg loop. */
9422 1.1 mrg se->expr = ss_info->data.scalar.value;
9423 1.1 mrg if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
9424 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
9425 1.1 mrg
9426 1.1 mrg se->string_length = ss_info->string_length;
9427 1.1 mrg gfc_advance_se_ss_chain (se);
9428 1.1 mrg return;
9429 1.1 mrg }
9430 1.1 mrg
9431 1.1 mrg /* We need to convert the expressions for the iso_c_binding derived types.
9432 1.1 mrg C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
9433 1.1 mrg null_pointer_node. C_PTR and C_FUNPTR are converted to match the
9434 1.1 mrg typespec for the C_PTR and C_FUNPTR symbols, which has already been
9435 1.1 mrg updated to be an integer with a kind equal to the size of a (void *). */
9436 1.1 mrg if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
9437 1.1 mrg && expr->ts.u.derived->attr.is_bind_c)
9438 1.1 mrg {
9439 1.1 mrg if (expr->expr_type == EXPR_VARIABLE
9440 1.1 mrg && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
9441 1.1 mrg || expr->symtree->n.sym->intmod_sym_id
9442 1.1 mrg == ISOCBINDING_NULL_FUNPTR))
9443 1.1 mrg {
9444 1.1 mrg /* Set expr_type to EXPR_NULL, which will result in
9445 1.1 mrg null_pointer_node being used below. */
9446 1.1 mrg expr->expr_type = EXPR_NULL;
9447 1.1 mrg }
9448 1.1 mrg else
9449 1.1 mrg {
9450 1.1 mrg /* Update the type/kind of the expression to be what the new
9451 1.1 mrg type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
9452 1.1 mrg expr->ts.type = BT_INTEGER;
9453 1.1 mrg expr->ts.f90_type = BT_VOID;
9454 1.1 mrg expr->ts.kind = gfc_index_integer_kind;
9455 1.1 mrg }
9456 1.1 mrg }
9457 1.1 mrg
9458 1.1 mrg gfc_fix_class_refs (expr);
9459 1.1 mrg
9460 1.1 mrg switch (expr->expr_type)
9461 1.1 mrg {
9462 1.1 mrg case EXPR_OP:
9463 1.1 mrg gfc_conv_expr_op (se, expr);
9464 1.1 mrg break;
9465 1.1 mrg
9466 1.1 mrg case EXPR_FUNCTION:
9467 1.1 mrg gfc_conv_function_expr (se, expr);
9468 1.1 mrg break;
9469 1.1 mrg
9470 1.1 mrg case EXPR_CONSTANT:
9471 1.1 mrg gfc_conv_constant (se, expr);
9472 1.1 mrg break;
9473 1.1 mrg
9474 1.1 mrg case EXPR_VARIABLE:
9475 1.1 mrg gfc_conv_variable (se, expr);
9476 1.1 mrg break;
9477 1.1 mrg
9478 1.1 mrg case EXPR_NULL:
9479 1.1 mrg se->expr = null_pointer_node;
9480 1.1 mrg break;
9481 1.1 mrg
9482 1.1 mrg case EXPR_SUBSTRING:
9483 1.1 mrg gfc_conv_substring_expr (se, expr);
9484 1.1 mrg break;
9485 1.1 mrg
9486 1.1 mrg case EXPR_STRUCTURE:
9487 1.1 mrg gfc_conv_structure (se, expr, 0);
9488 1.1 mrg break;
9489 1.1 mrg
9490 1.1 mrg case EXPR_ARRAY:
9491 1.1 mrg gfc_conv_array_constructor_expr (se, expr);
9492 1.1 mrg break;
9493 1.1 mrg
9494 1.1 mrg default:
9495 1.1 mrg gcc_unreachable ();
9496 1.1 mrg break;
9497 1.1 mrg }
9498 1.1 mrg }
9499 1.1 mrg
9500 1.1 mrg /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9501 1.1 mrg of an assignment. */
9502 1.1 mrg void
9503 1.1 mrg gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9504 1.1 mrg {
9505 1.1 mrg gfc_conv_expr (se, expr);
9506 1.1 mrg /* All numeric lvalues should have empty post chains. If not we need to
9507 1.1 mrg figure out a way of rewriting an lvalue so that it has no post chain. */
9508 1.1 mrg gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
9509 1.1 mrg }
9510 1.1 mrg
9511 1.1 mrg /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9512 1.1 mrg numeric expressions. Used for scalar values where inserting cleanup code
9513 1.1 mrg is inconvenient. */
9514 1.1 mrg void
9515 1.1 mrg gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9516 1.1 mrg {
9517 1.1 mrg tree val;
9518 1.1 mrg
9519 1.1 mrg gcc_assert (expr->ts.type != BT_CHARACTER);
9520 1.1 mrg gfc_conv_expr (se, expr);
9521 1.1 mrg if (se->post.head)
9522 1.1 mrg {
9523 1.1 mrg val = gfc_create_var (TREE_TYPE (se->expr), NULL);
9524 1.1 mrg gfc_add_modify (&se->pre, val, se->expr);
9525 1.1 mrg se->expr = val;
9526 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post);
9527 1.1 mrg }
9528 1.1 mrg }
9529 1.1 mrg
9530 1.1 mrg /* Helper to translate an expression and convert it to a particular type. */
9531 1.1 mrg void
9532 1.1 mrg gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9533 1.1 mrg {
9534 1.1 mrg gfc_conv_expr_val (se, expr);
9535 1.1 mrg se->expr = convert (type, se->expr);
9536 1.1 mrg }
9537 1.1 mrg
9538 1.1 mrg
9539 1.1 mrg /* Converts an expression so that it can be passed by reference. Scalar
9540 1.1 mrg values only. */
9541 1.1 mrg
9542 1.1 mrg void
9543 1.1 mrg gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
9544 1.1 mrg {
9545 1.1 mrg gfc_ss *ss;
9546 1.1 mrg tree var;
9547 1.1 mrg
9548 1.1 mrg ss = se->ss;
9549 1.1 mrg if (ss && ss->info->expr == expr
9550 1.1 mrg && ss->info->type == GFC_SS_REFERENCE)
9551 1.1 mrg {
9552 1.1 mrg /* Returns a reference to the scalar evaluated outside the loop
9553 1.1 mrg for this case. */
9554 1.1 mrg gfc_conv_expr (se, expr);
9555 1.1 mrg
9556 1.1 mrg if (expr->ts.type == BT_CHARACTER
9557 1.1 mrg && expr->expr_type != EXPR_FUNCTION)
9558 1.1 mrg gfc_conv_string_parameter (se);
9559 1.1 mrg else
9560 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9561 1.1 mrg
9562 1.1 mrg return;
9563 1.1 mrg }
9564 1.1 mrg
9565 1.1 mrg if (expr->ts.type == BT_CHARACTER)
9566 1.1 mrg {
9567 1.1 mrg gfc_conv_expr (se, expr);
9568 1.1 mrg gfc_conv_string_parameter (se);
9569 1.1 mrg return;
9570 1.1 mrg }
9571 1.1 mrg
9572 1.1 mrg if (expr->expr_type == EXPR_VARIABLE)
9573 1.1 mrg {
9574 1.1 mrg se->want_pointer = 1;
9575 1.1 mrg gfc_conv_expr (se, expr);
9576 1.1 mrg if (se->post.head)
9577 1.1 mrg {
9578 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9579 1.1 mrg gfc_add_modify (&se->pre, var, se->expr);
9580 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post);
9581 1.1 mrg se->expr = var;
9582 1.1 mrg }
9583 1.1 mrg return;
9584 1.1 mrg }
9585 1.1 mrg
9586 1.1 mrg if (expr->expr_type == EXPR_FUNCTION
9587 1.1 mrg && ((expr->value.function.esym
9588 1.1 mrg && expr->value.function.esym->result
9589 1.1 mrg && expr->value.function.esym->result->attr.pointer
9590 1.1 mrg && !expr->value.function.esym->result->attr.dimension)
9591 1.1 mrg || (!expr->value.function.esym && !expr->ref
9592 1.1 mrg && expr->symtree->n.sym->attr.pointer
9593 1.1 mrg && !expr->symtree->n.sym->attr.dimension)))
9594 1.1 mrg {
9595 1.1 mrg se->want_pointer = 1;
9596 1.1 mrg gfc_conv_expr (se, expr);
9597 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9598 1.1 mrg gfc_add_modify (&se->pre, var, se->expr);
9599 1.1 mrg se->expr = var;
9600 1.1 mrg return;
9601 1.1 mrg }
9602 1.1 mrg
9603 1.1 mrg gfc_conv_expr (se, expr);
9604 1.1 mrg
9605 1.1 mrg /* Create a temporary var to hold the value. */
9606 1.1 mrg if (TREE_CONSTANT (se->expr))
9607 1.1 mrg {
9608 1.1 mrg tree tmp = se->expr;
9609 1.1 mrg STRIP_TYPE_NOPS (tmp);
9610 1.1 mrg var = build_decl (input_location,
9611 1.1 mrg CONST_DECL, NULL, TREE_TYPE (tmp));
9612 1.1 mrg DECL_INITIAL (var) = tmp;
9613 1.1 mrg TREE_STATIC (var) = 1;
9614 1.1 mrg pushdecl (var);
9615 1.1 mrg }
9616 1.1 mrg else
9617 1.1 mrg {
9618 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9619 1.1 mrg gfc_add_modify (&se->pre, var, se->expr);
9620 1.1 mrg }
9621 1.1 mrg
9622 1.1 mrg if (!expr->must_finalize)
9623 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post);
9624 1.1 mrg
9625 1.1 mrg /* Take the address of that value. */
9626 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, var);
9627 1.1 mrg }
9628 1.1 mrg
9629 1.1 mrg
9630 1.1 mrg /* Get the _len component for an unlimited polymorphic expression. */
9631 1.1 mrg
9632 1.1 mrg static tree
9633 1.1 mrg trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9634 1.1 mrg {
9635 1.1 mrg gfc_se se;
9636 1.1 mrg gfc_ref *ref = expr->ref;
9637 1.1 mrg
9638 1.1 mrg gfc_init_se (&se, NULL);
9639 1.1 mrg while (ref && ref->next)
9640 1.1 mrg ref = ref->next;
9641 1.1 mrg gfc_add_len_component (expr);
9642 1.1 mrg gfc_conv_expr (&se, expr);
9643 1.1 mrg gfc_add_block_to_block (block, &se.pre);
9644 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
9645 1.1 mrg if (ref)
9646 1.1 mrg {
9647 1.1 mrg gfc_free_ref_list (ref->next);
9648 1.1 mrg ref->next = NULL;
9649 1.1 mrg }
9650 1.1 mrg else
9651 1.1 mrg {
9652 1.1 mrg gfc_free_ref_list (expr->ref);
9653 1.1 mrg expr->ref = NULL;
9654 1.1 mrg }
9655 1.1 mrg return se.expr;
9656 1.1 mrg }
9657 1.1 mrg
9658 1.1 mrg
9659 1.1 mrg /* Assign _vptr and _len components as appropriate. BLOCK should be a
9660 1.1 mrg statement-list outside of the scalarizer-loop. When code is generated, that
9661 1.1 mrg depends on the scalarized expression, it is added to RSE.PRE.
9662 1.1 mrg Returns le's _vptr tree and when set the len expressions in to_lenp and
9663 1.1 mrg from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9664 1.1 mrg expression. */
9665 1.1 mrg
9666 1.1 mrg static tree
9667 1.1 mrg trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9668 1.1 mrg gfc_expr * re, gfc_se *rse,
9669 1.1 mrg tree * to_lenp, tree * from_lenp)
9670 1.1 mrg {
9671 1.1 mrg gfc_se se;
9672 1.1 mrg gfc_expr * vptr_expr;
9673 1.1 mrg tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9674 1.1 mrg bool set_vptr = false, temp_rhs = false;
9675 1.1 mrg stmtblock_t *pre = block;
9676 1.1 mrg tree class_expr = NULL_TREE;
9677 1.1 mrg
9678 1.1 mrg /* Create a temporary for complicated expressions. */
9679 1.1 mrg if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9680 1.1 mrg && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9681 1.1 mrg {
9682 1.1 mrg if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9683 1.1 mrg class_expr = gfc_get_class_from_expr (rse->expr);
9684 1.1 mrg
9685 1.1 mrg if (rse->loop)
9686 1.1 mrg pre = &rse->loop->pre;
9687 1.1 mrg else
9688 1.1 mrg pre = &rse->pre;
9689 1.1 mrg
9690 1.1 mrg if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9691 1.1 mrg {
9692 1.1 mrg tmp = TREE_OPERAND (rse->expr, 0);
9693 1.1 mrg tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9694 1.1 mrg gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9695 1.1 mrg }
9696 1.1 mrg else
9697 1.1 mrg {
9698 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9699 1.1 mrg gfc_add_modify (&rse->pre, tmp, rse->expr);
9700 1.1 mrg }
9701 1.1 mrg
9702 1.1 mrg rse->expr = tmp;
9703 1.1 mrg temp_rhs = true;
9704 1.1 mrg }
9705 1.1 mrg
9706 1.1 mrg /* Get the _vptr for the left-hand side expression. */
9707 1.1 mrg gfc_init_se (&se, NULL);
9708 1.1 mrg vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9709 1.1 mrg if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9710 1.1 mrg {
9711 1.1 mrg /* Care about _len for unlimited polymorphic entities. */
9712 1.1 mrg if (UNLIMITED_POLY (vptr_expr)
9713 1.1 mrg || (vptr_expr->ts.type == BT_DERIVED
9714 1.1 mrg && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9715 1.1 mrg to_len = trans_get_upoly_len (block, vptr_expr);
9716 1.1 mrg gfc_add_vptr_component (vptr_expr);
9717 1.1 mrg set_vptr = true;
9718 1.1 mrg }
9719 1.1 mrg else
9720 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9721 1.1 mrg se.want_pointer = 1;
9722 1.1 mrg gfc_conv_expr (&se, vptr_expr);
9723 1.1 mrg gfc_free_expr (vptr_expr);
9724 1.1 mrg gfc_add_block_to_block (block, &se.pre);
9725 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
9726 1.1 mrg lhs_vptr = se.expr;
9727 1.1 mrg STRIP_NOPS (lhs_vptr);
9728 1.1 mrg
9729 1.1 mrg /* Set the _vptr only when the left-hand side of the assignment is a
9730 1.1 mrg class-object. */
9731 1.1 mrg if (set_vptr)
9732 1.1 mrg {
9733 1.1 mrg /* Get the vptr from the rhs expression only, when it is variable.
9734 1.1 mrg Functions are expected to be assigned to a temporary beforehand. */
9735 1.1 mrg vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
9736 1.1 mrg ? gfc_find_and_cut_at_last_class_ref (re)
9737 1.1 mrg : NULL;
9738 1.1 mrg if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9739 1.1 mrg {
9740 1.1 mrg if (to_len != NULL_TREE)
9741 1.1 mrg {
9742 1.1 mrg /* Get the _len information from the rhs. */
9743 1.1 mrg if (UNLIMITED_POLY (vptr_expr)
9744 1.1 mrg || (vptr_expr->ts.type == BT_DERIVED
9745 1.1 mrg && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9746 1.1 mrg from_len = trans_get_upoly_len (block, vptr_expr);
9747 1.1 mrg }
9748 1.1 mrg gfc_add_vptr_component (vptr_expr);
9749 1.1 mrg }
9750 1.1 mrg else
9751 1.1 mrg {
9752 1.1 mrg if (re->expr_type == EXPR_VARIABLE
9753 1.1 mrg && DECL_P (re->symtree->n.sym->backend_decl)
9754 1.1 mrg && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9755 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9756 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9757 1.1 mrg re->symtree->n.sym->backend_decl))))
9758 1.1 mrg {
9759 1.1 mrg vptr_expr = NULL;
9760 1.1 mrg se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9761 1.1 mrg re->symtree->n.sym->backend_decl));
9762 1.1 mrg if (to_len)
9763 1.1 mrg from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9764 1.1 mrg re->symtree->n.sym->backend_decl));
9765 1.1 mrg }
9766 1.1 mrg else if (temp_rhs && re->ts.type == BT_CLASS)
9767 1.1 mrg {
9768 1.1 mrg vptr_expr = NULL;
9769 1.1 mrg if (class_expr)
9770 1.1 mrg tmp = class_expr;
9771 1.1 mrg else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9772 1.1 mrg tmp = gfc_get_class_from_expr (rse->expr);
9773 1.1 mrg else
9774 1.1 mrg tmp = rse->expr;
9775 1.1 mrg
9776 1.1 mrg se.expr = gfc_class_vptr_get (tmp);
9777 1.1 mrg if (UNLIMITED_POLY (re))
9778 1.1 mrg from_len = gfc_class_len_get (tmp);
9779 1.1 mrg
9780 1.1 mrg }
9781 1.1 mrg else if (re->expr_type != EXPR_NULL)
9782 1.1 mrg /* Only when rhs is non-NULL use its declared type for vptr
9783 1.1 mrg initialisation. */
9784 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
9785 1.1 mrg else
9786 1.1 mrg /* When the rhs is NULL use the vtab of lhs' declared type. */
9787 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9788 1.1 mrg }
9789 1.1 mrg
9790 1.1 mrg if (vptr_expr)
9791 1.1 mrg {
9792 1.1 mrg gfc_init_se (&se, NULL);
9793 1.1 mrg se.want_pointer = 1;
9794 1.1 mrg gfc_conv_expr (&se, vptr_expr);
9795 1.1 mrg gfc_free_expr (vptr_expr);
9796 1.1 mrg gfc_add_block_to_block (block, &se.pre);
9797 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
9798 1.1 mrg }
9799 1.1 mrg gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
9800 1.1 mrg se.expr));
9801 1.1 mrg
9802 1.1 mrg if (to_len != NULL_TREE)
9803 1.1 mrg {
9804 1.1 mrg /* The _len component needs to be set. Figure how to get the
9805 1.1 mrg value of the right-hand side. */
9806 1.1 mrg if (from_len == NULL_TREE)
9807 1.1 mrg {
9808 1.1 mrg if (rse->string_length != NULL_TREE)
9809 1.1 mrg from_len = rse->string_length;
9810 1.1 mrg else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
9811 1.1 mrg {
9812 1.1 mrg gfc_init_se (&se, NULL);
9813 1.1 mrg gfc_conv_expr (&se, re->ts.u.cl->length);
9814 1.1 mrg gfc_add_block_to_block (block, &se.pre);
9815 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
9816 1.1 mrg from_len = gfc_evaluate_now (se.expr, block);
9817 1.1 mrg }
9818 1.1 mrg else
9819 1.1 mrg from_len = build_zero_cst (gfc_charlen_type_node);
9820 1.1 mrg }
9821 1.1 mrg gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
9822 1.1 mrg from_len));
9823 1.1 mrg }
9824 1.1 mrg }
9825 1.1 mrg
9826 1.1 mrg /* Return the _len trees only, when requested. */
9827 1.1 mrg if (to_lenp)
9828 1.1 mrg *to_lenp = to_len;
9829 1.1 mrg if (from_lenp)
9830 1.1 mrg *from_lenp = from_len;
9831 1.1 mrg return lhs_vptr;
9832 1.1 mrg }
9833 1.1 mrg
9834 1.1 mrg
9835 1.1 mrg /* Assign tokens for pointer components. */
9836 1.1 mrg
9837 1.1 mrg static void
9838 1.1 mrg trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
9839 1.1 mrg gfc_expr *expr2)
9840 1.1 mrg {
9841 1.1 mrg symbol_attribute lhs_attr, rhs_attr;
9842 1.1 mrg tree tmp, lhs_tok, rhs_tok;
9843 1.1 mrg /* Flag to indicated component refs on the rhs. */
9844 1.1 mrg bool rhs_cr;
9845 1.1 mrg
9846 1.1 mrg lhs_attr = gfc_caf_attr (expr1);
9847 1.1 mrg if (expr2->expr_type != EXPR_NULL)
9848 1.1 mrg {
9849 1.1 mrg rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
9850 1.1 mrg if (lhs_attr.codimension && rhs_attr.codimension)
9851 1.1 mrg {
9852 1.1 mrg lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9853 1.1 mrg lhs_tok = build_fold_indirect_ref (lhs_tok);
9854 1.1 mrg
9855 1.1 mrg if (rhs_cr)
9856 1.1 mrg rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
9857 1.1 mrg else
9858 1.1 mrg {
9859 1.1 mrg tree caf_decl;
9860 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (expr2);
9861 1.1 mrg gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
9862 1.1 mrg NULL_TREE, NULL);
9863 1.1 mrg }
9864 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9865 1.1 mrg lhs_tok,
9866 1.1 mrg fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
9867 1.1 mrg gfc_prepend_expr_to_block (&lse->post, tmp);
9868 1.1 mrg }
9869 1.1 mrg }
9870 1.1 mrg else if (lhs_attr.codimension)
9871 1.1 mrg {
9872 1.1 mrg lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9873 1.1 mrg lhs_tok = build_fold_indirect_ref (lhs_tok);
9874 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9875 1.1 mrg lhs_tok, null_pointer_node);
9876 1.1 mrg gfc_prepend_expr_to_block (&lse->post, tmp);
9877 1.1 mrg }
9878 1.1 mrg }
9879 1.1 mrg
9880 1.1 mrg
9881 1.1 mrg /* Do everything that is needed for a CLASS function expr2. */
9882 1.1 mrg
9883 1.1 mrg static tree
9884 1.1 mrg trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
9885 1.1 mrg gfc_expr *expr1, gfc_expr *expr2)
9886 1.1 mrg {
9887 1.1 mrg tree expr1_vptr = NULL_TREE;
9888 1.1 mrg tree tmp;
9889 1.1 mrg
9890 1.1 mrg gfc_conv_function_expr (rse, expr2);
9891 1.1 mrg rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
9892 1.1 mrg
9893 1.1 mrg if (expr1->ts.type != BT_CLASS)
9894 1.1 mrg rse->expr = gfc_class_data_get (rse->expr);
9895 1.1 mrg else
9896 1.1 mrg {
9897 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
9898 1.1 mrg expr2, rse,
9899 1.1 mrg NULL, NULL);
9900 1.1 mrg gfc_add_block_to_block (block, &rse->pre);
9901 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
9902 1.1 mrg gfc_add_modify (&lse->pre, tmp, rse->expr);
9903 1.1 mrg
9904 1.1 mrg gfc_add_modify (&lse->pre, expr1_vptr,
9905 1.1 mrg fold_convert (TREE_TYPE (expr1_vptr),
9906 1.1 mrg gfc_class_vptr_get (tmp)));
9907 1.1 mrg rse->expr = gfc_class_data_get (tmp);
9908 1.1 mrg }
9909 1.1 mrg
9910 1.1 mrg return expr1_vptr;
9911 1.1 mrg }
9912 1.1 mrg
9913 1.1 mrg
9914 1.1 mrg tree
9915 1.1 mrg gfc_trans_pointer_assign (gfc_code * code)
9916 1.1 mrg {
9917 1.1 mrg return gfc_trans_pointer_assignment (code->expr1, code->expr2);
9918 1.1 mrg }
9919 1.1 mrg
9920 1.1 mrg
9921 1.1 mrg /* Generate code for a pointer assignment. */
9922 1.1 mrg
9923 1.1 mrg tree
9924 1.1 mrg gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
9925 1.1 mrg {
9926 1.1 mrg gfc_se lse;
9927 1.1 mrg gfc_se rse;
9928 1.1 mrg stmtblock_t block;
9929 1.1 mrg tree desc;
9930 1.1 mrg tree tmp;
9931 1.1 mrg tree expr1_vptr = NULL_TREE;
9932 1.1 mrg bool scalar, non_proc_ptr_assign;
9933 1.1 mrg gfc_ss *ss;
9934 1.1 mrg
9935 1.1 mrg gfc_start_block (&block);
9936 1.1 mrg
9937 1.1 mrg gfc_init_se (&lse, NULL);
9938 1.1 mrg
9939 1.1 mrg /* Usually testing whether this is not a proc pointer assignment. */
9940 1.1 mrg non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
9941 1.1 mrg && expr2->expr_type == EXPR_VARIABLE
9942 1.1 mrg && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
9943 1.1 mrg
9944 1.1 mrg /* Check whether the expression is a scalar or not; we cannot use
9945 1.1 mrg expr1->rank as it can be nonzero for proc pointers. */
9946 1.1 mrg ss = gfc_walk_expr (expr1);
9947 1.1 mrg scalar = ss == gfc_ss_terminator;
9948 1.1 mrg if (!scalar)
9949 1.1 mrg gfc_free_ss_chain (ss);
9950 1.1 mrg
9951 1.1 mrg if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
9952 1.1 mrg && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
9953 1.1 mrg {
9954 1.1 mrg gfc_add_data_component (expr2);
9955 1.1 mrg /* The following is required as gfc_add_data_component doesn't
9956 1.1 mrg update ts.type if there is a trailing REF_ARRAY. */
9957 1.1 mrg expr2->ts.type = BT_DERIVED;
9958 1.1 mrg }
9959 1.1 mrg
9960 1.1 mrg if (scalar)
9961 1.1 mrg {
9962 1.1 mrg /* Scalar pointers. */
9963 1.1 mrg lse.want_pointer = 1;
9964 1.1 mrg gfc_conv_expr (&lse, expr1);
9965 1.1 mrg gfc_init_se (&rse, NULL);
9966 1.1 mrg rse.want_pointer = 1;
9967 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9968 1.1 mrg trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
9969 1.1 mrg else
9970 1.1 mrg gfc_conv_expr (&rse, expr2);
9971 1.1 mrg
9972 1.1 mrg if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
9973 1.1 mrg {
9974 1.1 mrg trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
9975 1.1 mrg NULL);
9976 1.1 mrg lse.expr = gfc_class_data_get (lse.expr);
9977 1.1 mrg }
9978 1.1 mrg
9979 1.1 mrg if (expr1->symtree->n.sym->attr.proc_pointer
9980 1.1 mrg && expr1->symtree->n.sym->attr.dummy)
9981 1.1 mrg lse.expr = build_fold_indirect_ref_loc (input_location,
9982 1.1 mrg lse.expr);
9983 1.1 mrg
9984 1.1 mrg if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
9985 1.1 mrg && expr2->symtree->n.sym->attr.dummy)
9986 1.1 mrg rse.expr = build_fold_indirect_ref_loc (input_location,
9987 1.1 mrg rse.expr);
9988 1.1 mrg
9989 1.1 mrg gfc_add_block_to_block (&block, &lse.pre);
9990 1.1 mrg gfc_add_block_to_block (&block, &rse.pre);
9991 1.1 mrg
9992 1.1 mrg /* Check character lengths if character expression. The test is only
9993 1.1 mrg really added if -fbounds-check is enabled. Exclude deferred
9994 1.1 mrg character length lefthand sides. */
9995 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
9996 1.1 mrg && !expr1->ts.deferred
9997 1.1 mrg && !expr1->symtree->n.sym->attr.proc_pointer
9998 1.1 mrg && !gfc_is_proc_ptr_comp (expr1))
9999 1.1 mrg {
10000 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER);
10001 1.1 mrg gcc_assert (lse.string_length && rse.string_length);
10002 1.1 mrg gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10003 1.1 mrg lse.string_length, rse.string_length,
10004 1.1 mrg &block);
10005 1.1 mrg }
10006 1.1 mrg
10007 1.1 mrg /* The assignment to an deferred character length sets the string
10008 1.1 mrg length to that of the rhs. */
10009 1.1 mrg if (expr1->ts.deferred)
10010 1.1 mrg {
10011 1.1 mrg if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
10012 1.1 mrg gfc_add_modify (&block, lse.string_length,
10013 1.1 mrg fold_convert (TREE_TYPE (lse.string_length),
10014 1.1 mrg rse.string_length));
10015 1.1 mrg else if (lse.string_length != NULL)
10016 1.1 mrg gfc_add_modify (&block, lse.string_length,
10017 1.1 mrg build_zero_cst (TREE_TYPE (lse.string_length)));
10018 1.1 mrg }
10019 1.1 mrg
10020 1.1 mrg gfc_add_modify (&block, lse.expr,
10021 1.1 mrg fold_convert (TREE_TYPE (lse.expr), rse.expr));
10022 1.1 mrg
10023 1.1 mrg /* Also set the tokens for pointer components in derived typed
10024 1.1 mrg coarrays. */
10025 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
10026 1.1 mrg trans_caf_token_assign (&lse, &rse, expr1, expr2);
10027 1.1 mrg
10028 1.1 mrg gfc_add_block_to_block (&block, &rse.post);
10029 1.1 mrg gfc_add_block_to_block (&block, &lse.post);
10030 1.1 mrg }
10031 1.1 mrg else
10032 1.1 mrg {
10033 1.1 mrg gfc_ref* remap;
10034 1.1 mrg bool rank_remap;
10035 1.1 mrg tree strlen_lhs;
10036 1.1 mrg tree strlen_rhs = NULL_TREE;
10037 1.1 mrg
10038 1.1 mrg /* Array pointer. Find the last reference on the LHS and if it is an
10039 1.1 mrg array section ref, we're dealing with bounds remapping. In this case,
10040 1.1 mrg set it to AR_FULL so that gfc_conv_expr_descriptor does
10041 1.1 mrg not see it and process the bounds remapping afterwards explicitly. */
10042 1.1 mrg for (remap = expr1->ref; remap; remap = remap->next)
10043 1.1 mrg if (!remap->next && remap->type == REF_ARRAY
10044 1.1 mrg && remap->u.ar.type == AR_SECTION)
10045 1.1 mrg break;
10046 1.1 mrg rank_remap = (remap && remap->u.ar.end[0]);
10047 1.1 mrg
10048 1.1 mrg if (remap && expr2->expr_type == EXPR_NULL)
10049 1.1 mrg {
10050 1.1 mrg gfc_error ("If bounds remapping is specified at %L, "
10051 1.1 mrg "the pointer target shall not be NULL", &expr1->where);
10052 1.1 mrg return NULL_TREE;
10053 1.1 mrg }
10054 1.1 mrg
10055 1.1 mrg gfc_init_se (&lse, NULL);
10056 1.1 mrg if (remap)
10057 1.1 mrg lse.descriptor_only = 1;
10058 1.1 mrg gfc_conv_expr_descriptor (&lse, expr1);
10059 1.1 mrg strlen_lhs = lse.string_length;
10060 1.1 mrg desc = lse.expr;
10061 1.1 mrg
10062 1.1 mrg if (expr2->expr_type == EXPR_NULL)
10063 1.1 mrg {
10064 1.1 mrg /* Just set the data pointer to null. */
10065 1.1 mrg gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
10066 1.1 mrg }
10067 1.1 mrg else if (rank_remap)
10068 1.1 mrg {
10069 1.1 mrg /* If we are rank-remapping, just get the RHS's descriptor and
10070 1.1 mrg process this later on. */
10071 1.1 mrg gfc_init_se (&rse, NULL);
10072 1.1 mrg rse.direct_byref = 1;
10073 1.1 mrg rse.byref_noassign = 1;
10074 1.1 mrg
10075 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10076 1.1 mrg expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
10077 1.1 mrg expr1, expr2);
10078 1.1 mrg else if (expr2->expr_type == EXPR_FUNCTION)
10079 1.1 mrg {
10080 1.1 mrg tree bound[GFC_MAX_DIMENSIONS];
10081 1.1 mrg int i;
10082 1.1 mrg
10083 1.1 mrg for (i = 0; i < expr2->rank; i++)
10084 1.1 mrg bound[i] = NULL_TREE;
10085 1.1 mrg tmp = gfc_typenode_for_spec (&expr2->ts);
10086 1.1 mrg tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
10087 1.1 mrg bound, bound, 0,
10088 1.1 mrg GFC_ARRAY_POINTER_CONT, false);
10089 1.1 mrg tmp = gfc_create_var (tmp, "ptrtemp");
10090 1.1 mrg rse.descriptor_only = 0;
10091 1.1 mrg rse.expr = tmp;
10092 1.1 mrg rse.direct_byref = 1;
10093 1.1 mrg gfc_conv_expr_descriptor (&rse, expr2);
10094 1.1 mrg strlen_rhs = rse.string_length;
10095 1.1 mrg rse.expr = tmp;
10096 1.1 mrg }
10097 1.1 mrg else
10098 1.1 mrg {
10099 1.1 mrg gfc_conv_expr_descriptor (&rse, expr2);
10100 1.1 mrg strlen_rhs = rse.string_length;
10101 1.1 mrg if (expr1->ts.type == BT_CLASS)
10102 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10103 1.1 mrg expr2, &rse,
10104 1.1 mrg NULL, NULL);
10105 1.1 mrg }
10106 1.1 mrg }
10107 1.1 mrg else if (expr2->expr_type == EXPR_VARIABLE)
10108 1.1 mrg {
10109 1.1 mrg /* Assign directly to the LHS's descriptor. */
10110 1.1 mrg lse.descriptor_only = 0;
10111 1.1 mrg lse.direct_byref = 1;
10112 1.1 mrg gfc_conv_expr_descriptor (&lse, expr2);
10113 1.1 mrg strlen_rhs = lse.string_length;
10114 1.1 mrg gfc_init_se (&rse, NULL);
10115 1.1 mrg
10116 1.1 mrg if (expr1->ts.type == BT_CLASS)
10117 1.1 mrg {
10118 1.1 mrg rse.expr = NULL_TREE;
10119 1.1 mrg rse.string_length = strlen_rhs;
10120 1.1 mrg trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
10121 1.1 mrg NULL, NULL);
10122 1.1 mrg }
10123 1.1 mrg
10124 1.1 mrg if (remap == NULL)
10125 1.1 mrg {
10126 1.1 mrg /* If the target is not a whole array, use the target array
10127 1.1 mrg reference for remap. */
10128 1.1 mrg for (remap = expr2->ref; remap; remap = remap->next)
10129 1.1 mrg if (remap->type == REF_ARRAY
10130 1.1 mrg && remap->u.ar.type == AR_FULL
10131 1.1 mrg && remap->next)
10132 1.1 mrg break;
10133 1.1 mrg }
10134 1.1 mrg }
10135 1.1 mrg else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10136 1.1 mrg {
10137 1.1 mrg gfc_init_se (&rse, NULL);
10138 1.1 mrg rse.want_pointer = 1;
10139 1.1 mrg gfc_conv_function_expr (&rse, expr2);
10140 1.1 mrg if (expr1->ts.type != BT_CLASS)
10141 1.1 mrg {
10142 1.1 mrg rse.expr = gfc_class_data_get (rse.expr);
10143 1.1 mrg gfc_add_modify (&lse.pre, desc, rse.expr);
10144 1.1 mrg /* Set the lhs span. */
10145 1.1 mrg tmp = TREE_TYPE (rse.expr);
10146 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10147 1.1 mrg tmp = fold_convert (gfc_array_index_type, tmp);
10148 1.1 mrg gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
10149 1.1 mrg }
10150 1.1 mrg else
10151 1.1 mrg {
10152 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10153 1.1 mrg expr2, &rse, NULL,
10154 1.1 mrg NULL);
10155 1.1 mrg gfc_add_block_to_block (&block, &rse.pre);
10156 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
10157 1.1 mrg gfc_add_modify (&lse.pre, tmp, rse.expr);
10158 1.1 mrg
10159 1.1 mrg gfc_add_modify (&lse.pre, expr1_vptr,
10160 1.1 mrg fold_convert (TREE_TYPE (expr1_vptr),
10161 1.1 mrg gfc_class_vptr_get (tmp)));
10162 1.1 mrg rse.expr = gfc_class_data_get (tmp);
10163 1.1 mrg gfc_add_modify (&lse.pre, desc, rse.expr);
10164 1.1 mrg }
10165 1.1 mrg }
10166 1.1 mrg else
10167 1.1 mrg {
10168 1.1 mrg /* Assign to a temporary descriptor and then copy that
10169 1.1 mrg temporary to the pointer. */
10170 1.1 mrg tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
10171 1.1 mrg lse.descriptor_only = 0;
10172 1.1 mrg lse.expr = tmp;
10173 1.1 mrg lse.direct_byref = 1;
10174 1.1 mrg gfc_conv_expr_descriptor (&lse, expr2);
10175 1.1 mrg strlen_rhs = lse.string_length;
10176 1.1 mrg gfc_add_modify (&lse.pre, desc, tmp);
10177 1.1 mrg }
10178 1.1 mrg
10179 1.1 mrg if (expr1->ts.type == BT_CHARACTER
10180 1.1 mrg && expr1->symtree->n.sym->ts.deferred
10181 1.1 mrg && expr1->symtree->n.sym->ts.u.cl->backend_decl
10182 1.1 mrg && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
10183 1.1 mrg {
10184 1.1 mrg tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
10185 1.1 mrg if (expr2->expr_type != EXPR_NULL)
10186 1.1 mrg gfc_add_modify (&block, tmp,
10187 1.1 mrg fold_convert (TREE_TYPE (tmp), strlen_rhs));
10188 1.1 mrg else
10189 1.1 mrg gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
10190 1.1 mrg }
10191 1.1 mrg
10192 1.1 mrg gfc_add_block_to_block (&block, &lse.pre);
10193 1.1 mrg if (rank_remap)
10194 1.1 mrg gfc_add_block_to_block (&block, &rse.pre);
10195 1.1 mrg
10196 1.1 mrg /* If we do bounds remapping, update LHS descriptor accordingly. */
10197 1.1 mrg if (remap)
10198 1.1 mrg {
10199 1.1 mrg int dim;
10200 1.1 mrg gcc_assert (remap->u.ar.dimen == expr1->rank);
10201 1.1 mrg
10202 1.1 mrg if (rank_remap)
10203 1.1 mrg {
10204 1.1 mrg /* Do rank remapping. We already have the RHS's descriptor
10205 1.1 mrg converted in rse and now have to build the correct LHS
10206 1.1 mrg descriptor for it. */
10207 1.1 mrg
10208 1.1 mrg tree dtype, data, span;
10209 1.1 mrg tree offs, stride;
10210 1.1 mrg tree lbound, ubound;
10211 1.1 mrg
10212 1.1 mrg /* Set dtype. */
10213 1.1 mrg dtype = gfc_conv_descriptor_dtype (desc);
10214 1.1 mrg tmp = gfc_get_dtype (TREE_TYPE (desc));
10215 1.1 mrg gfc_add_modify (&block, dtype, tmp);
10216 1.1 mrg
10217 1.1 mrg /* Copy data pointer. */
10218 1.1 mrg data = gfc_conv_descriptor_data_get (rse.expr);
10219 1.1 mrg gfc_conv_descriptor_data_set (&block, desc, data);
10220 1.1 mrg
10221 1.1 mrg /* Copy the span. */
10222 1.1 mrg if (TREE_CODE (rse.expr) == VAR_DECL
10223 1.1 mrg && GFC_DECL_PTR_ARRAY_P (rse.expr))
10224 1.1 mrg span = gfc_conv_descriptor_span_get (rse.expr);
10225 1.1 mrg else
10226 1.1 mrg {
10227 1.1 mrg tmp = TREE_TYPE (rse.expr);
10228 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10229 1.1 mrg span = fold_convert (gfc_array_index_type, tmp);
10230 1.1 mrg }
10231 1.1 mrg gfc_conv_descriptor_span_set (&block, desc, span);
10232 1.1 mrg
10233 1.1 mrg /* Copy offset but adjust it such that it would correspond
10234 1.1 mrg to a lbound of zero. */
10235 1.1 mrg offs = gfc_conv_descriptor_offset_get (rse.expr);
10236 1.1 mrg for (dim = 0; dim < expr2->rank; ++dim)
10237 1.1 mrg {
10238 1.1 mrg stride = gfc_conv_descriptor_stride_get (rse.expr,
10239 1.1 mrg gfc_rank_cst[dim]);
10240 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (rse.expr,
10241 1.1 mrg gfc_rank_cst[dim]);
10242 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
10243 1.1 mrg gfc_array_index_type, stride, lbound);
10244 1.1 mrg offs = fold_build2_loc (input_location, PLUS_EXPR,
10245 1.1 mrg gfc_array_index_type, offs, tmp);
10246 1.1 mrg }
10247 1.1 mrg gfc_conv_descriptor_offset_set (&block, desc, offs);
10248 1.1 mrg
10249 1.1 mrg /* Set the bounds as declared for the LHS and calculate strides as
10250 1.1 mrg well as another offset update accordingly. */
10251 1.1 mrg stride = gfc_conv_descriptor_stride_get (rse.expr,
10252 1.1 mrg gfc_rank_cst[0]);
10253 1.1 mrg for (dim = 0; dim < expr1->rank; ++dim)
10254 1.1 mrg {
10255 1.1 mrg gfc_se lower_se;
10256 1.1 mrg gfc_se upper_se;
10257 1.1 mrg
10258 1.1 mrg gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
10259 1.1 mrg
10260 1.1 mrg /* Convert declared bounds. */
10261 1.1 mrg gfc_init_se (&lower_se, NULL);
10262 1.1 mrg gfc_init_se (&upper_se, NULL);
10263 1.1 mrg gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
10264 1.1 mrg gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
10265 1.1 mrg
10266 1.1 mrg gfc_add_block_to_block (&block, &lower_se.pre);
10267 1.1 mrg gfc_add_block_to_block (&block, &upper_se.pre);
10268 1.1 mrg
10269 1.1 mrg lbound = fold_convert (gfc_array_index_type, lower_se.expr);
10270 1.1 mrg ubound = fold_convert (gfc_array_index_type, upper_se.expr);
10271 1.1 mrg
10272 1.1 mrg lbound = gfc_evaluate_now (lbound, &block);
10273 1.1 mrg ubound = gfc_evaluate_now (ubound, &block);
10274 1.1 mrg
10275 1.1 mrg gfc_add_block_to_block (&block, &lower_se.post);
10276 1.1 mrg gfc_add_block_to_block (&block, &upper_se.post);
10277 1.1 mrg
10278 1.1 mrg /* Set bounds in descriptor. */
10279 1.1 mrg gfc_conv_descriptor_lbound_set (&block, desc,
10280 1.1 mrg gfc_rank_cst[dim], lbound);
10281 1.1 mrg gfc_conv_descriptor_ubound_set (&block, desc,
10282 1.1 mrg gfc_rank_cst[dim], ubound);
10283 1.1 mrg
10284 1.1 mrg /* Set stride. */
10285 1.1 mrg stride = gfc_evaluate_now (stride, &block);
10286 1.1 mrg gfc_conv_descriptor_stride_set (&block, desc,
10287 1.1 mrg gfc_rank_cst[dim], stride);
10288 1.1 mrg
10289 1.1 mrg /* Update offset. */
10290 1.1 mrg offs = gfc_conv_descriptor_offset_get (desc);
10291 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
10292 1.1 mrg gfc_array_index_type, lbound, stride);
10293 1.1 mrg offs = fold_build2_loc (input_location, MINUS_EXPR,
10294 1.1 mrg gfc_array_index_type, offs, tmp);
10295 1.1 mrg offs = gfc_evaluate_now (offs, &block);
10296 1.1 mrg gfc_conv_descriptor_offset_set (&block, desc, offs);
10297 1.1 mrg
10298 1.1 mrg /* Update stride. */
10299 1.1 mrg tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
10300 1.1 mrg stride = fold_build2_loc (input_location, MULT_EXPR,
10301 1.1 mrg gfc_array_index_type, stride, tmp);
10302 1.1 mrg }
10303 1.1 mrg }
10304 1.1 mrg else
10305 1.1 mrg {
10306 1.1 mrg /* Bounds remapping. Just shift the lower bounds. */
10307 1.1 mrg
10308 1.1 mrg gcc_assert (expr1->rank == expr2->rank);
10309 1.1 mrg
10310 1.1 mrg for (dim = 0; dim < remap->u.ar.dimen; ++dim)
10311 1.1 mrg {
10312 1.1 mrg gfc_se lbound_se;
10313 1.1 mrg
10314 1.1 mrg gcc_assert (!remap->u.ar.end[dim]);
10315 1.1 mrg gfc_init_se (&lbound_se, NULL);
10316 1.1 mrg if (remap->u.ar.start[dim])
10317 1.1 mrg {
10318 1.1 mrg gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
10319 1.1 mrg gfc_add_block_to_block (&block, &lbound_se.pre);
10320 1.1 mrg }
10321 1.1 mrg else
10322 1.1 mrg /* This remap arises from a target that is not a whole
10323 1.1 mrg array. The start expressions will be NULL but we need
10324 1.1 mrg the lbounds to be one. */
10325 1.1 mrg lbound_se.expr = gfc_index_one_node;
10326 1.1 mrg gfc_conv_shift_descriptor_lbound (&block, desc,
10327 1.1 mrg dim, lbound_se.expr);
10328 1.1 mrg gfc_add_block_to_block (&block, &lbound_se.post);
10329 1.1 mrg }
10330 1.1 mrg }
10331 1.1 mrg }
10332 1.1 mrg
10333 1.1 mrg /* If rank remapping was done, check with -fcheck=bounds that
10334 1.1 mrg the target is at least as large as the pointer. */
10335 1.1 mrg if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
10336 1.1 mrg {
10337 1.1 mrg tree lsize, rsize;
10338 1.1 mrg tree fault;
10339 1.1 mrg const char* msg;
10340 1.1 mrg
10341 1.1 mrg lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
10342 1.1 mrg rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
10343 1.1 mrg
10344 1.1 mrg lsize = gfc_evaluate_now (lsize, &block);
10345 1.1 mrg rsize = gfc_evaluate_now (rsize, &block);
10346 1.1 mrg fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
10347 1.1 mrg rsize, lsize);
10348 1.1 mrg
10349 1.1 mrg msg = _("Target of rank remapping is too small (%ld < %ld)");
10350 1.1 mrg gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
10351 1.1 mrg msg, rsize, lsize);
10352 1.1 mrg }
10353 1.1 mrg
10354 1.1 mrg /* Check string lengths if applicable. The check is only really added
10355 1.1 mrg to the output code if -fbounds-check is enabled. */
10356 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
10357 1.1 mrg {
10358 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER);
10359 1.1 mrg gcc_assert (strlen_lhs && strlen_rhs);
10360 1.1 mrg gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10361 1.1 mrg strlen_lhs, strlen_rhs, &block);
10362 1.1 mrg }
10363 1.1 mrg
10364 1.1 mrg gfc_add_block_to_block (&block, &lse.post);
10365 1.1 mrg if (rank_remap)
10366 1.1 mrg gfc_add_block_to_block (&block, &rse.post);
10367 1.1 mrg }
10368 1.1 mrg
10369 1.1 mrg return gfc_finish_block (&block);
10370 1.1 mrg }
10371 1.1 mrg
10372 1.1 mrg
10373 1.1 mrg /* Makes sure se is suitable for passing as a function string parameter. */
10374 1.1 mrg /* TODO: Need to check all callers of this function. It may be abused. */
10375 1.1 mrg
10376 1.1 mrg void
10377 1.1 mrg gfc_conv_string_parameter (gfc_se * se)
10378 1.1 mrg {
10379 1.1 mrg tree type;
10380 1.1 mrg
10381 1.1 mrg if (TREE_CODE (se->expr) == STRING_CST)
10382 1.1 mrg {
10383 1.1 mrg type = TREE_TYPE (TREE_TYPE (se->expr));
10384 1.1 mrg se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10385 1.1 mrg return;
10386 1.1 mrg }
10387 1.1 mrg
10388 1.1 mrg if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
10389 1.1 mrg || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
10390 1.1 mrg && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
10391 1.1 mrg {
10392 1.1 mrg if (TREE_CODE (se->expr) != INDIRECT_REF)
10393 1.1 mrg {
10394 1.1 mrg type = TREE_TYPE (se->expr);
10395 1.1 mrg se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10396 1.1 mrg }
10397 1.1 mrg else
10398 1.1 mrg {
10399 1.1 mrg type = gfc_get_character_type_len (gfc_default_character_kind,
10400 1.1 mrg se->string_length);
10401 1.1 mrg type = build_pointer_type (type);
10402 1.1 mrg se->expr = gfc_build_addr_expr (type, se->expr);
10403 1.1 mrg }
10404 1.1 mrg }
10405 1.1 mrg
10406 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
10407 1.1 mrg }
10408 1.1 mrg
10409 1.1 mrg
10410 1.1 mrg /* Generate code for assignment of scalar variables. Includes character
10411 1.1 mrg strings and derived types with allocatable components.
10412 1.1 mrg If you know that the LHS has no allocations, set dealloc to false.
10413 1.1 mrg
10414 1.1 mrg DEEP_COPY has no effect if the typespec TS is not a derived type with
10415 1.1 mrg allocatable components. Otherwise, if it is set, an explicit copy of each
10416 1.1 mrg allocatable component is made. This is necessary as a simple copy of the
10417 1.1 mrg whole object would copy array descriptors as is, so that the lhs's
10418 1.1 mrg allocatable components would point to the rhs's after the assignment.
10419 1.1 mrg Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
10420 1.1 mrg necessary if the rhs is a non-pointer function, as the allocatable components
10421 1.1 mrg are not accessible by other means than the function's result after the
10422 1.1 mrg function has returned. It is even more subtle when temporaries are involved,
10423 1.1 mrg as the two following examples show:
10424 1.1 mrg 1. When we evaluate an array constructor, a temporary is created. Thus
10425 1.1 mrg there is theoretically no alias possible. However, no deep copy is
10426 1.1 mrg made for this temporary, so that if the constructor is made of one or
10427 1.1 mrg more variable with allocatable components, those components still point
10428 1.1 mrg to the variable's: DEEP_COPY should be set for the assignment from the
10429 1.1 mrg temporary to the lhs in that case.
10430 1.1 mrg 2. When assigning a scalar to an array, we evaluate the scalar value out
10431 1.1 mrg of the loop, store it into a temporary variable, and assign from that.
10432 1.1 mrg In that case, deep copying when assigning to the temporary would be a
10433 1.1 mrg waste of resources; however deep copies should happen when assigning from
10434 1.1 mrg the temporary to each array element: again DEEP_COPY should be set for
10435 1.1 mrg the assignment from the temporary to the lhs. */
10436 1.1 mrg
10437 1.1 mrg tree
10438 1.1 mrg gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
10439 1.1 mrg bool deep_copy, bool dealloc, bool in_coarray)
10440 1.1 mrg {
10441 1.1 mrg stmtblock_t block;
10442 1.1 mrg tree tmp;
10443 1.1 mrg tree cond;
10444 1.1 mrg
10445 1.1 mrg gfc_init_block (&block);
10446 1.1 mrg
10447 1.1 mrg if (ts.type == BT_CHARACTER)
10448 1.1 mrg {
10449 1.1 mrg tree rlen = NULL;
10450 1.1 mrg tree llen = NULL;
10451 1.1 mrg
10452 1.1 mrg if (lse->string_length != NULL_TREE)
10453 1.1 mrg {
10454 1.1 mrg gfc_conv_string_parameter (lse);
10455 1.1 mrg gfc_add_block_to_block (&block, &lse->pre);
10456 1.1 mrg llen = lse->string_length;
10457 1.1 mrg }
10458 1.1 mrg
10459 1.1 mrg if (rse->string_length != NULL_TREE)
10460 1.1 mrg {
10461 1.1 mrg gfc_conv_string_parameter (rse);
10462 1.1 mrg gfc_add_block_to_block (&block, &rse->pre);
10463 1.1 mrg rlen = rse->string_length;
10464 1.1 mrg }
10465 1.1 mrg
10466 1.1 mrg gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10467 1.1 mrg rse->expr, ts.kind);
10468 1.1 mrg }
10469 1.1 mrg else if (gfc_bt_struct (ts.type)
10470 1.1 mrg && (ts.u.derived->attr.alloc_comp
10471 1.1 mrg || (deep_copy && ts.u.derived->attr.pdt_type)))
10472 1.1 mrg {
10473 1.1 mrg tree tmp_var = NULL_TREE;
10474 1.1 mrg cond = NULL_TREE;
10475 1.1 mrg
10476 1.1 mrg /* Are the rhs and the lhs the same? */
10477 1.1 mrg if (deep_copy)
10478 1.1 mrg {
10479 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10480 1.1 mrg gfc_build_addr_expr (NULL_TREE, lse->expr),
10481 1.1 mrg gfc_build_addr_expr (NULL_TREE, rse->expr));
10482 1.1 mrg cond = gfc_evaluate_now (cond, &lse->pre);
10483 1.1 mrg }
10484 1.1 mrg
10485 1.1 mrg /* Deallocate the lhs allocated components as long as it is not
10486 1.1 mrg the same as the rhs. This must be done following the assignment
10487 1.1 mrg to prevent deallocating data that could be used in the rhs
10488 1.1 mrg expression. */
10489 1.1 mrg if (dealloc)
10490 1.1 mrg {
10491 1.1 mrg tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10492 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
10493 1.1 mrg if (deep_copy)
10494 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10495 1.1 mrg tmp);
10496 1.1 mrg gfc_add_expr_to_block (&lse->post, tmp);
10497 1.1 mrg }
10498 1.1 mrg
10499 1.1 mrg gfc_add_block_to_block (&block, &rse->pre);
10500 1.1 mrg gfc_add_block_to_block (&block, &lse->pre);
10501 1.1 mrg
10502 1.1 mrg gfc_add_modify (&block, lse->expr,
10503 1.1 mrg fold_convert (TREE_TYPE (lse->expr), rse->expr));
10504 1.1 mrg
10505 1.1 mrg /* Restore pointer address of coarray components. */
10506 1.1 mrg if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
10507 1.1 mrg {
10508 1.1 mrg tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10509 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10510 1.1 mrg tmp);
10511 1.1 mrg gfc_add_expr_to_block (&block, tmp);
10512 1.1 mrg }
10513 1.1 mrg
10514 1.1 mrg /* Do a deep copy if the rhs is a variable, if it is not the
10515 1.1 mrg same as the lhs. */
10516 1.1 mrg if (deep_copy)
10517 1.1 mrg {
10518 1.1 mrg int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10519 1.1 mrg | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10520 1.1 mrg tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10521 1.1 mrg caf_mode);
10522 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10523 1.1 mrg tmp);
10524 1.1 mrg gfc_add_expr_to_block (&block, tmp);
10525 1.1 mrg }
10526 1.1 mrg }
10527 1.1 mrg else if (gfc_bt_struct (ts.type))
10528 1.1 mrg {
10529 1.1 mrg gfc_add_block_to_block (&block, &lse->pre);
10530 1.1 mrg gfc_add_block_to_block (&block, &rse->pre);
10531 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10532 1.1 mrg TREE_TYPE (lse->expr), rse->expr);
10533 1.1 mrg gfc_add_modify (&block, lse->expr, tmp);
10534 1.1 mrg }
10535 1.1 mrg /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
10536 1.1 mrg else if (ts.type == BT_CLASS)
10537 1.1 mrg {
10538 1.1 mrg gfc_add_block_to_block (&block, &lse->pre);
10539 1.1 mrg gfc_add_block_to_block (&block, &rse->pre);
10540 1.1 mrg
10541 1.1 mrg if (!trans_scalar_class_assign (&block, lse, rse))
10542 1.1 mrg {
10543 1.1 mrg /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10544 1.1 mrg for the lhs which ensures that class data rhs cast as a string assigns
10545 1.1 mrg correctly. */
10546 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10547 1.1 mrg TREE_TYPE (rse->expr), lse->expr);
10548 1.1 mrg gfc_add_modify (&block, tmp, rse->expr);
10549 1.1 mrg }
10550 1.1 mrg }
10551 1.1 mrg else if (ts.type != BT_CLASS)
10552 1.1 mrg {
10553 1.1 mrg gfc_add_block_to_block (&block, &lse->pre);
10554 1.1 mrg gfc_add_block_to_block (&block, &rse->pre);
10555 1.1 mrg
10556 1.1 mrg gfc_add_modify (&block, lse->expr,
10557 1.1 mrg fold_convert (TREE_TYPE (lse->expr), rse->expr));
10558 1.1 mrg }
10559 1.1 mrg
10560 1.1 mrg gfc_add_block_to_block (&block, &lse->post);
10561 1.1 mrg gfc_add_block_to_block (&block, &rse->post);
10562 1.1 mrg
10563 1.1 mrg return gfc_finish_block (&block);
10564 1.1 mrg }
10565 1.1 mrg
10566 1.1 mrg
10567 1.1 mrg /* There are quite a lot of restrictions on the optimisation in using an
10568 1.1 mrg array function assign without a temporary. */
10569 1.1 mrg
10570 1.1 mrg static bool
10571 1.1 mrg arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
10572 1.1 mrg {
10573 1.1 mrg gfc_ref * ref;
10574 1.1 mrg bool seen_array_ref;
10575 1.1 mrg bool c = false;
10576 1.1 mrg gfc_symbol *sym = expr1->symtree->n.sym;
10577 1.1 mrg
10578 1.1 mrg /* Play it safe with class functions assigned to a derived type. */
10579 1.1 mrg if (gfc_is_class_array_function (expr2)
10580 1.1 mrg && expr1->ts.type == BT_DERIVED)
10581 1.1 mrg return true;
10582 1.1 mrg
10583 1.1 mrg /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10584 1.1 mrg if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
10585 1.1 mrg return true;
10586 1.1 mrg
10587 1.1 mrg /* Elemental functions are scalarized so that they don't need a
10588 1.1 mrg temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10589 1.1 mrg they would need special treatment in gfc_trans_arrayfunc_assign. */
10590 1.1 mrg if (expr2->value.function.esym != NULL
10591 1.1 mrg && expr2->value.function.esym->attr.elemental)
10592 1.1 mrg return true;
10593 1.1 mrg
10594 1.1 mrg /* Need a temporary if rhs is not FULL or a contiguous section. */
10595 1.1 mrg if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
10596 1.1 mrg return true;
10597 1.1 mrg
10598 1.1 mrg /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
10599 1.1 mrg if (gfc_ref_needs_temporary_p (expr1->ref))
10600 1.1 mrg return true;
10601 1.1 mrg
10602 1.1 mrg /* Functions returning pointers or allocatables need temporaries. */
10603 1.1 mrg if (gfc_expr_attr (expr2).pointer
10604 1.1 mrg || gfc_expr_attr (expr2).allocatable)
10605 1.1 mrg return true;
10606 1.1 mrg
10607 1.1 mrg /* Character array functions need temporaries unless the
10608 1.1 mrg character lengths are the same. */
10609 1.1 mrg if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10610 1.1 mrg {
10611 1.1 mrg if (expr1->ts.u.cl->length == NULL
10612 1.1 mrg || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10613 1.1 mrg return true;
10614 1.1 mrg
10615 1.1 mrg if (expr2->ts.u.cl->length == NULL
10616 1.1 mrg || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10617 1.1 mrg return true;
10618 1.1 mrg
10619 1.1 mrg if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10620 1.1 mrg expr2->ts.u.cl->length->value.integer) != 0)
10621 1.1 mrg return true;
10622 1.1 mrg }
10623 1.1 mrg
10624 1.1 mrg /* Check that no LHS component references appear during an array
10625 1.1 mrg reference. This is needed because we do not have the means to
10626 1.1 mrg span any arbitrary stride with an array descriptor. This check
10627 1.1 mrg is not needed for the rhs because the function result has to be
10628 1.1 mrg a complete type. */
10629 1.1 mrg seen_array_ref = false;
10630 1.1 mrg for (ref = expr1->ref; ref; ref = ref->next)
10631 1.1 mrg {
10632 1.1 mrg if (ref->type == REF_ARRAY)
10633 1.1 mrg seen_array_ref= true;
10634 1.1 mrg else if (ref->type == REF_COMPONENT && seen_array_ref)
10635 1.1 mrg return true;
10636 1.1 mrg }
10637 1.1 mrg
10638 1.1 mrg /* Check for a dependency. */
10639 1.1 mrg if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10640 1.1 mrg expr2->value.function.esym,
10641 1.1 mrg expr2->value.function.actual,
10642 1.1 mrg NOT_ELEMENTAL))
10643 1.1 mrg return true;
10644 1.1 mrg
10645 1.1 mrg /* If we have reached here with an intrinsic function, we do not
10646 1.1 mrg need a temporary except in the particular case that reallocation
10647 1.1 mrg on assignment is active and the lhs is allocatable and a target,
10648 1.1 mrg or a pointer which may be a subref pointer. FIXME: The last
10649 1.1 mrg condition can go away when we use span in the intrinsics
10650 1.1 mrg directly.*/
10651 1.1 mrg if (expr2->value.function.isym)
10652 1.1 mrg return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10653 1.1 mrg || (sym->attr.pointer && sym->attr.subref_array_pointer);
10654 1.1 mrg
10655 1.1 mrg /* If the LHS is a dummy, we need a temporary if it is not
10656 1.1 mrg INTENT(OUT). */
10657 1.1 mrg if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10658 1.1 mrg return true;
10659 1.1 mrg
10660 1.1 mrg /* If the lhs has been host_associated, is in common, a pointer or is
10661 1.1 mrg a target and the function is not using a RESULT variable, aliasing
10662 1.1 mrg can occur and a temporary is needed. */
10663 1.1 mrg if ((sym->attr.host_assoc
10664 1.1 mrg || sym->attr.in_common
10665 1.1 mrg || sym->attr.pointer
10666 1.1 mrg || sym->attr.cray_pointee
10667 1.1 mrg || sym->attr.target)
10668 1.1 mrg && expr2->symtree != NULL
10669 1.1 mrg && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10670 1.1 mrg return true;
10671 1.1 mrg
10672 1.1 mrg /* A PURE function can unconditionally be called without a temporary. */
10673 1.1 mrg if (expr2->value.function.esym != NULL
10674 1.1 mrg && expr2->value.function.esym->attr.pure)
10675 1.1 mrg return false;
10676 1.1 mrg
10677 1.1 mrg /* Implicit_pure functions are those which could legally be declared
10678 1.1 mrg to be PURE. */
10679 1.1 mrg if (expr2->value.function.esym != NULL
10680 1.1 mrg && expr2->value.function.esym->attr.implicit_pure)
10681 1.1 mrg return false;
10682 1.1 mrg
10683 1.1 mrg if (!sym->attr.use_assoc
10684 1.1 mrg && !sym->attr.in_common
10685 1.1 mrg && !sym->attr.pointer
10686 1.1 mrg && !sym->attr.target
10687 1.1 mrg && !sym->attr.cray_pointee
10688 1.1 mrg && expr2->value.function.esym)
10689 1.1 mrg {
10690 1.1 mrg /* A temporary is not needed if the function is not contained and
10691 1.1 mrg the variable is local or host associated and not a pointer or
10692 1.1 mrg a target. */
10693 1.1 mrg if (!expr2->value.function.esym->attr.contained)
10694 1.1 mrg return false;
10695 1.1 mrg
10696 1.1 mrg /* A temporary is not needed if the lhs has never been host
10697 1.1 mrg associated and the procedure is contained. */
10698 1.1 mrg else if (!sym->attr.host_assoc)
10699 1.1 mrg return false;
10700 1.1 mrg
10701 1.1 mrg /* A temporary is not needed if the variable is local and not
10702 1.1 mrg a pointer, a target or a result. */
10703 1.1 mrg if (sym->ns->parent
10704 1.1 mrg && expr2->value.function.esym->ns == sym->ns->parent)
10705 1.1 mrg return false;
10706 1.1 mrg }
10707 1.1 mrg
10708 1.1 mrg /* Default to temporary use. */
10709 1.1 mrg return true;
10710 1.1 mrg }
10711 1.1 mrg
10712 1.1 mrg
10713 1.1 mrg /* Provide the loop info so that the lhs descriptor can be built for
10714 1.1 mrg reallocatable assignments from extrinsic function calls. */
10715 1.1 mrg
10716 1.1 mrg static void
10717 1.1 mrg realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10718 1.1 mrg gfc_loopinfo *loop)
10719 1.1 mrg {
10720 1.1 mrg /* Signal that the function call should not be made by
10721 1.1 mrg gfc_conv_loop_setup. */
10722 1.1 mrg se->ss->is_alloc_lhs = 1;
10723 1.1 mrg gfc_init_loopinfo (loop);
10724 1.1 mrg gfc_add_ss_to_loop (loop, *ss);
10725 1.1 mrg gfc_add_ss_to_loop (loop, se->ss);
10726 1.1 mrg gfc_conv_ss_startstride (loop);
10727 1.1 mrg gfc_conv_loop_setup (loop, where);
10728 1.1 mrg gfc_copy_loopinfo_to_se (se, loop);
10729 1.1 mrg gfc_add_block_to_block (&se->pre, &loop->pre);
10730 1.1 mrg gfc_add_block_to_block (&se->pre, &loop->post);
10731 1.1 mrg se->ss->is_alloc_lhs = 0;
10732 1.1 mrg }
10733 1.1 mrg
10734 1.1 mrg
10735 1.1 mrg /* For assignment to a reallocatable lhs from intrinsic functions,
10736 1.1 mrg replace the se.expr (ie. the result) with a temporary descriptor.
10737 1.1 mrg Null the data field so that the library allocates space for the
10738 1.1 mrg result. Free the data of the original descriptor after the function,
10739 1.1 mrg in case it appears in an argument expression and transfer the
10740 1.1 mrg result to the original descriptor. */
10741 1.1 mrg
10742 1.1 mrg static void
10743 1.1 mrg fcncall_realloc_result (gfc_se *se, int rank)
10744 1.1 mrg {
10745 1.1 mrg tree desc;
10746 1.1 mrg tree res_desc;
10747 1.1 mrg tree tmp;
10748 1.1 mrg tree offset;
10749 1.1 mrg tree zero_cond;
10750 1.1 mrg tree not_same_shape;
10751 1.1 mrg stmtblock_t shape_block;
10752 1.1 mrg int n;
10753 1.1 mrg
10754 1.1 mrg /* Use the allocation done by the library. Substitute the lhs
10755 1.1 mrg descriptor with a copy, whose data field is nulled.*/
10756 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, se->expr);
10757 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (desc)))
10758 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, desc);
10759 1.1 mrg
10760 1.1 mrg /* Unallocated, the descriptor does not have a dtype. */
10761 1.1 mrg tmp = gfc_conv_descriptor_dtype (desc);
10762 1.1 mrg gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
10763 1.1 mrg
10764 1.1 mrg res_desc = gfc_evaluate_now (desc, &se->pre);
10765 1.1 mrg gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
10766 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
10767 1.1 mrg
10768 1.1 mrg /* Free the lhs after the function call and copy the result data to
10769 1.1 mrg the lhs descriptor. */
10770 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc);
10771 1.1 mrg zero_cond = fold_build2_loc (input_location, EQ_EXPR,
10772 1.1 mrg logical_type_node, tmp,
10773 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0));
10774 1.1 mrg zero_cond = gfc_evaluate_now (zero_cond, &se->post);
10775 1.1 mrg tmp = gfc_call_free (tmp);
10776 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
10777 1.1 mrg
10778 1.1 mrg tmp = gfc_conv_descriptor_data_get (res_desc);
10779 1.1 mrg gfc_conv_descriptor_data_set (&se->post, desc, tmp);
10780 1.1 mrg
10781 1.1 mrg /* Check that the shapes are the same between lhs and expression.
10782 1.1 mrg The evaluation of the shape is done in 'shape_block' to avoid
10783 1.1 mrg unitialized warnings from the lhs bounds. */
10784 1.1 mrg not_same_shape = boolean_false_node;
10785 1.1 mrg gfc_start_block (&shape_block);
10786 1.1 mrg for (n = 0 ; n < rank; n++)
10787 1.1 mrg {
10788 1.1 mrg tree tmp1;
10789 1.1 mrg tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10790 1.1 mrg tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
10791 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
10792 1.1 mrg gfc_array_index_type, tmp, tmp1);
10793 1.1 mrg tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10794 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR,
10795 1.1 mrg gfc_array_index_type, tmp, tmp1);
10796 1.1 mrg tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10797 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR,
10798 1.1 mrg gfc_array_index_type, tmp, tmp1);
10799 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
10800 1.1 mrg logical_type_node, tmp,
10801 1.1 mrg gfc_index_zero_node);
10802 1.1 mrg tmp = gfc_evaluate_now (tmp, &shape_block);
10803 1.1 mrg if (n == 0)
10804 1.1 mrg not_same_shape = tmp;
10805 1.1 mrg else
10806 1.1 mrg not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10807 1.1 mrg logical_type_node, tmp,
10808 1.1 mrg not_same_shape);
10809 1.1 mrg }
10810 1.1 mrg
10811 1.1 mrg /* 'zero_cond' being true is equal to lhs not being allocated or the
10812 1.1 mrg shapes being different. */
10813 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
10814 1.1 mrg zero_cond, not_same_shape);
10815 1.1 mrg gfc_add_modify (&shape_block, zero_cond, tmp);
10816 1.1 mrg tmp = gfc_finish_block (&shape_block);
10817 1.1 mrg tmp = build3_v (COND_EXPR, zero_cond,
10818 1.1 mrg build_empty_stmt (input_location), tmp);
10819 1.1 mrg gfc_add_expr_to_block (&se->post, tmp);
10820 1.1 mrg
10821 1.1 mrg /* Now reset the bounds returned from the function call to bounds based
10822 1.1 mrg on the lhs lbounds, except where the lhs is not allocated or the shapes
10823 1.1 mrg of 'variable and 'expr' are different. Set the offset accordingly. */
10824 1.1 mrg offset = gfc_index_zero_node;
10825 1.1 mrg for (n = 0 ; n < rank; n++)
10826 1.1 mrg {
10827 1.1 mrg tree lbound;
10828 1.1 mrg
10829 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10830 1.1 mrg lbound = fold_build3_loc (input_location, COND_EXPR,
10831 1.1 mrg gfc_array_index_type, zero_cond,
10832 1.1 mrg gfc_index_one_node, lbound);
10833 1.1 mrg lbound = gfc_evaluate_now (lbound, &se->post);
10834 1.1 mrg
10835 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10836 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR,
10837 1.1 mrg gfc_array_index_type, tmp, lbound);
10838 1.1 mrg gfc_conv_descriptor_lbound_set (&se->post, desc,
10839 1.1 mrg gfc_rank_cst[n], lbound);
10840 1.1 mrg gfc_conv_descriptor_ubound_set (&se->post, desc,
10841 1.1 mrg gfc_rank_cst[n], tmp);
10842 1.1 mrg
10843 1.1 mrg /* Set stride and accumulate the offset. */
10844 1.1 mrg tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
10845 1.1 mrg gfc_conv_descriptor_stride_set (&se->post, desc,
10846 1.1 mrg gfc_rank_cst[n], tmp);
10847 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
10848 1.1 mrg gfc_array_index_type, lbound, tmp);
10849 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR,
10850 1.1 mrg gfc_array_index_type, offset, tmp);
10851 1.1 mrg offset = gfc_evaluate_now (offset, &se->post);
10852 1.1 mrg }
10853 1.1 mrg
10854 1.1 mrg gfc_conv_descriptor_offset_set (&se->post, desc, offset);
10855 1.1 mrg }
10856 1.1 mrg
10857 1.1 mrg
10858 1.1 mrg
10859 1.1 mrg /* Try to translate array(:) = func (...), where func is a transformational
10860 1.1 mrg array function, without using a temporary. Returns NULL if this isn't the
10861 1.1 mrg case. */
10862 1.1 mrg
10863 1.1 mrg static tree
10864 1.1 mrg gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
10865 1.1 mrg {
10866 1.1 mrg gfc_se se;
10867 1.1 mrg gfc_ss *ss = NULL;
10868 1.1 mrg gfc_component *comp = NULL;
10869 1.1 mrg gfc_loopinfo loop;
10870 1.1 mrg
10871 1.1 mrg if (arrayfunc_assign_needs_temporary (expr1, expr2))
10872 1.1 mrg return NULL;
10873 1.1 mrg
10874 1.1 mrg /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10875 1.1 mrg functions. */
10876 1.1 mrg comp = gfc_get_proc_ptr_comp (expr2);
10877 1.1 mrg
10878 1.1 mrg if (!(expr2->value.function.isym
10879 1.1 mrg || (comp && comp->attr.dimension)
10880 1.1 mrg || (!comp && gfc_return_by_reference (expr2->value.function.esym)
10881 1.1 mrg && expr2->value.function.esym->result->attr.dimension)))
10882 1.1 mrg return NULL;
10883 1.1 mrg
10884 1.1 mrg gfc_init_se (&se, NULL);
10885 1.1 mrg gfc_start_block (&se.pre);
10886 1.1 mrg se.want_pointer = 1;
10887 1.1 mrg
10888 1.1 mrg gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
10889 1.1 mrg
10890 1.1 mrg if (expr1->ts.type == BT_DERIVED
10891 1.1 mrg && expr1->ts.u.derived->attr.alloc_comp)
10892 1.1 mrg {
10893 1.1 mrg tree tmp;
10894 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
10895 1.1 mrg expr1->rank);
10896 1.1 mrg gfc_add_expr_to_block (&se.pre, tmp);
10897 1.1 mrg }
10898 1.1 mrg
10899 1.1 mrg se.direct_byref = 1;
10900 1.1 mrg se.ss = gfc_walk_expr (expr2);
10901 1.1 mrg gcc_assert (se.ss != gfc_ss_terminator);
10902 1.1 mrg
10903 1.1 mrg /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10904 1.1 mrg This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10905 1.1 mrg Clearly, this cannot be done for an allocatable function result, since
10906 1.1 mrg the shape of the result is unknown and, in any case, the function must
10907 1.1 mrg correctly take care of the reallocation internally. For intrinsic
10908 1.1 mrg calls, the array data is freed and the library takes care of allocation.
10909 1.1 mrg TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
10910 1.1 mrg to the library. */
10911 1.1 mrg if (flag_realloc_lhs
10912 1.1 mrg && gfc_is_reallocatable_lhs (expr1)
10913 1.1 mrg && !gfc_expr_attr (expr1).codimension
10914 1.1 mrg && !gfc_is_coindexed (expr1)
10915 1.1 mrg && !(expr2->value.function.esym
10916 1.1 mrg && expr2->value.function.esym->result->attr.allocatable))
10917 1.1 mrg {
10918 1.1 mrg realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10919 1.1 mrg
10920 1.1 mrg if (!expr2->value.function.isym)
10921 1.1 mrg {
10922 1.1 mrg ss = gfc_walk_expr (expr1);
10923 1.1 mrg gcc_assert (ss != gfc_ss_terminator);
10924 1.1 mrg
10925 1.1 mrg realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
10926 1.1 mrg ss->is_alloc_lhs = 1;
10927 1.1 mrg }
10928 1.1 mrg else
10929 1.1 mrg fcncall_realloc_result (&se, expr1->rank);
10930 1.1 mrg }
10931 1.1 mrg
10932 1.1 mrg gfc_conv_function_expr (&se, expr2);
10933 1.1 mrg gfc_add_block_to_block (&se.pre, &se.post);
10934 1.1 mrg
10935 1.1 mrg if (ss)
10936 1.1 mrg gfc_cleanup_loop (&loop);
10937 1.1 mrg else
10938 1.1 mrg gfc_free_ss_chain (se.ss);
10939 1.1 mrg
10940 1.1 mrg return gfc_finish_block (&se.pre);
10941 1.1 mrg }
10942 1.1 mrg
10943 1.1 mrg
10944 1.1 mrg /* Try to efficiently translate array(:) = 0. Return NULL if this
10945 1.1 mrg can't be done. */
10946 1.1 mrg
10947 1.1 mrg static tree
10948 1.1 mrg gfc_trans_zero_assign (gfc_expr * expr)
10949 1.1 mrg {
10950 1.1 mrg tree dest, len, type;
10951 1.1 mrg tree tmp;
10952 1.1 mrg gfc_symbol *sym;
10953 1.1 mrg
10954 1.1 mrg sym = expr->symtree->n.sym;
10955 1.1 mrg dest = gfc_get_symbol_decl (sym);
10956 1.1 mrg
10957 1.1 mrg type = TREE_TYPE (dest);
10958 1.1 mrg if (POINTER_TYPE_P (type))
10959 1.1 mrg type = TREE_TYPE (type);
10960 1.1 mrg if (!GFC_ARRAY_TYPE_P (type))
10961 1.1 mrg return NULL_TREE;
10962 1.1 mrg
10963 1.1 mrg /* Determine the length of the array. */
10964 1.1 mrg len = GFC_TYPE_ARRAY_SIZE (type);
10965 1.1 mrg if (!len || TREE_CODE (len) != INTEGER_CST)
10966 1.1 mrg return NULL_TREE;
10967 1.1 mrg
10968 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
10969 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10970 1.1 mrg fold_convert (gfc_array_index_type, tmp));
10971 1.1 mrg
10972 1.1 mrg /* If we are zeroing a local array avoid taking its address by emitting
10973 1.1 mrg a = {} instead. */
10974 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (dest)))
10975 1.1 mrg return build2_loc (input_location, MODIFY_EXPR, void_type_node,
10976 1.1 mrg dest, build_constructor (TREE_TYPE (dest),
10977 1.1 mrg NULL));
10978 1.1 mrg
10979 1.1 mrg /* Convert arguments to the correct types. */
10980 1.1 mrg dest = fold_convert (pvoid_type_node, dest);
10981 1.1 mrg len = fold_convert (size_type_node, len);
10982 1.1 mrg
10983 1.1 mrg /* Construct call to __builtin_memset. */
10984 1.1 mrg tmp = build_call_expr_loc (input_location,
10985 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMSET),
10986 1.1 mrg 3, dest, integer_zero_node, len);
10987 1.1 mrg return fold_convert (void_type_node, tmp);
10988 1.1 mrg }
10989 1.1 mrg
10990 1.1 mrg
10991 1.1 mrg /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10992 1.1 mrg that constructs the call to __builtin_memcpy. */
10993 1.1 mrg
10994 1.1 mrg tree
10995 1.1 mrg gfc_build_memcpy_call (tree dst, tree src, tree len)
10996 1.1 mrg {
10997 1.1 mrg tree tmp;
10998 1.1 mrg
10999 1.1 mrg /* Convert arguments to the correct types. */
11000 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (dst)))
11001 1.1 mrg dst = gfc_build_addr_expr (pvoid_type_node, dst);
11002 1.1 mrg else
11003 1.1 mrg dst = fold_convert (pvoid_type_node, dst);
11004 1.1 mrg
11005 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (src)))
11006 1.1 mrg src = gfc_build_addr_expr (pvoid_type_node, src);
11007 1.1 mrg else
11008 1.1 mrg src = fold_convert (pvoid_type_node, src);
11009 1.1 mrg
11010 1.1 mrg len = fold_convert (size_type_node, len);
11011 1.1 mrg
11012 1.1 mrg /* Construct call to __builtin_memcpy. */
11013 1.1 mrg tmp = build_call_expr_loc (input_location,
11014 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMCPY),
11015 1.1 mrg 3, dst, src, len);
11016 1.1 mrg return fold_convert (void_type_node, tmp);
11017 1.1 mrg }
11018 1.1 mrg
11019 1.1 mrg
11020 1.1 mrg /* Try to efficiently translate dst(:) = src(:). Return NULL if this
11021 1.1 mrg can't be done. EXPR1 is the destination/lhs and EXPR2 is the
11022 1.1 mrg source/rhs, both are gfc_full_array_ref_p which have been checked for
11023 1.1 mrg dependencies. */
11024 1.1 mrg
11025 1.1 mrg static tree
11026 1.1 mrg gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
11027 1.1 mrg {
11028 1.1 mrg tree dst, dlen, dtype;
11029 1.1 mrg tree src, slen, stype;
11030 1.1 mrg tree tmp;
11031 1.1 mrg
11032 1.1 mrg dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11033 1.1 mrg src = gfc_get_symbol_decl (expr2->symtree->n.sym);
11034 1.1 mrg
11035 1.1 mrg dtype = TREE_TYPE (dst);
11036 1.1 mrg if (POINTER_TYPE_P (dtype))
11037 1.1 mrg dtype = TREE_TYPE (dtype);
11038 1.1 mrg stype = TREE_TYPE (src);
11039 1.1 mrg if (POINTER_TYPE_P (stype))
11040 1.1 mrg stype = TREE_TYPE (stype);
11041 1.1 mrg
11042 1.1 mrg if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
11043 1.1 mrg return NULL_TREE;
11044 1.1 mrg
11045 1.1 mrg /* Determine the lengths of the arrays. */
11046 1.1 mrg dlen = GFC_TYPE_ARRAY_SIZE (dtype);
11047 1.1 mrg if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
11048 1.1 mrg return NULL_TREE;
11049 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11050 1.1 mrg dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11051 1.1 mrg dlen, fold_convert (gfc_array_index_type, tmp));
11052 1.1 mrg
11053 1.1 mrg slen = GFC_TYPE_ARRAY_SIZE (stype);
11054 1.1 mrg if (!slen || TREE_CODE (slen) != INTEGER_CST)
11055 1.1 mrg return NULL_TREE;
11056 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
11057 1.1 mrg slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11058 1.1 mrg slen, fold_convert (gfc_array_index_type, tmp));
11059 1.1 mrg
11060 1.1 mrg /* Sanity check that they are the same. This should always be
11061 1.1 mrg the case, as we should already have checked for conformance. */
11062 1.1 mrg if (!tree_int_cst_equal (slen, dlen))
11063 1.1 mrg return NULL_TREE;
11064 1.1 mrg
11065 1.1 mrg return gfc_build_memcpy_call (dst, src, dlen);
11066 1.1 mrg }
11067 1.1 mrg
11068 1.1 mrg
11069 1.1 mrg /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
11070 1.1 mrg this can't be done. EXPR1 is the destination/lhs for which
11071 1.1 mrg gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
11072 1.1 mrg
11073 1.1 mrg static tree
11074 1.1 mrg gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
11075 1.1 mrg {
11076 1.1 mrg unsigned HOST_WIDE_INT nelem;
11077 1.1 mrg tree dst, dtype;
11078 1.1 mrg tree src, stype;
11079 1.1 mrg tree len;
11080 1.1 mrg tree tmp;
11081 1.1 mrg
11082 1.1 mrg nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
11083 1.1 mrg if (nelem == 0)
11084 1.1 mrg return NULL_TREE;
11085 1.1 mrg
11086 1.1 mrg dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11087 1.1 mrg dtype = TREE_TYPE (dst);
11088 1.1 mrg if (POINTER_TYPE_P (dtype))
11089 1.1 mrg dtype = TREE_TYPE (dtype);
11090 1.1 mrg if (!GFC_ARRAY_TYPE_P (dtype))
11091 1.1 mrg return NULL_TREE;
11092 1.1 mrg
11093 1.1 mrg /* Determine the lengths of the array. */
11094 1.1 mrg len = GFC_TYPE_ARRAY_SIZE (dtype);
11095 1.1 mrg if (!len || TREE_CODE (len) != INTEGER_CST)
11096 1.1 mrg return NULL_TREE;
11097 1.1 mrg
11098 1.1 mrg /* Confirm that the constructor is the same size. */
11099 1.1 mrg if (compare_tree_int (len, nelem) != 0)
11100 1.1 mrg return NULL_TREE;
11101 1.1 mrg
11102 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11103 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
11104 1.1 mrg fold_convert (gfc_array_index_type, tmp));
11105 1.1 mrg
11106 1.1 mrg stype = gfc_typenode_for_spec (&expr2->ts);
11107 1.1 mrg src = gfc_build_constant_array_constructor (expr2, stype);
11108 1.1 mrg
11109 1.1 mrg return gfc_build_memcpy_call (dst, src, len);
11110 1.1 mrg }
11111 1.1 mrg
11112 1.1 mrg
11113 1.1 mrg /* Tells whether the expression is to be treated as a variable reference. */
11114 1.1 mrg
11115 1.1 mrg bool
11116 1.1 mrg gfc_expr_is_variable (gfc_expr *expr)
11117 1.1 mrg {
11118 1.1 mrg gfc_expr *arg;
11119 1.1 mrg gfc_component *comp;
11120 1.1 mrg gfc_symbol *func_ifc;
11121 1.1 mrg
11122 1.1 mrg if (expr->expr_type == EXPR_VARIABLE)
11123 1.1 mrg return true;
11124 1.1 mrg
11125 1.1 mrg arg = gfc_get_noncopying_intrinsic_argument (expr);
11126 1.1 mrg if (arg)
11127 1.1 mrg {
11128 1.1 mrg gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
11129 1.1 mrg return gfc_expr_is_variable (arg);
11130 1.1 mrg }
11131 1.1 mrg
11132 1.1 mrg /* A data-pointer-returning function should be considered as a variable
11133 1.1 mrg too. */
11134 1.1 mrg if (expr->expr_type == EXPR_FUNCTION
11135 1.1 mrg && expr->ref == NULL)
11136 1.1 mrg {
11137 1.1 mrg if (expr->value.function.isym != NULL)
11138 1.1 mrg return false;
11139 1.1 mrg
11140 1.1 mrg if (expr->value.function.esym != NULL)
11141 1.1 mrg {
11142 1.1 mrg func_ifc = expr->value.function.esym;
11143 1.1 mrg goto found_ifc;
11144 1.1 mrg }
11145 1.1 mrg gcc_assert (expr->symtree);
11146 1.1 mrg func_ifc = expr->symtree->n.sym;
11147 1.1 mrg goto found_ifc;
11148 1.1 mrg }
11149 1.1 mrg
11150 1.1 mrg comp = gfc_get_proc_ptr_comp (expr);
11151 1.1 mrg if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
11152 1.1 mrg && comp)
11153 1.1 mrg {
11154 1.1 mrg func_ifc = comp->ts.interface;
11155 1.1 mrg goto found_ifc;
11156 1.1 mrg }
11157 1.1 mrg
11158 1.1 mrg if (expr->expr_type == EXPR_COMPCALL)
11159 1.1 mrg {
11160 1.1 mrg gcc_assert (!expr->value.compcall.tbp->is_generic);
11161 1.1 mrg func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
11162 1.1 mrg goto found_ifc;
11163 1.1 mrg }
11164 1.1 mrg
11165 1.1 mrg return false;
11166 1.1 mrg
11167 1.1 mrg found_ifc:
11168 1.1 mrg gcc_assert (func_ifc->attr.function
11169 1.1 mrg && func_ifc->result != NULL);
11170 1.1 mrg return func_ifc->result->attr.pointer;
11171 1.1 mrg }
11172 1.1 mrg
11173 1.1 mrg
11174 1.1 mrg /* Is the lhs OK for automatic reallocation? */
11175 1.1 mrg
11176 1.1 mrg static bool
11177 1.1 mrg is_scalar_reallocatable_lhs (gfc_expr *expr)
11178 1.1 mrg {
11179 1.1 mrg gfc_ref * ref;
11180 1.1 mrg
11181 1.1 mrg /* An allocatable variable with no reference. */
11182 1.1 mrg if (expr->symtree->n.sym->attr.allocatable
11183 1.1 mrg && !expr->ref)
11184 1.1 mrg return true;
11185 1.1 mrg
11186 1.1 mrg /* All that can be left are allocatable components. However, we do
11187 1.1 mrg not check for allocatable components here because the expression
11188 1.1 mrg could be an allocatable component of a pointer component. */
11189 1.1 mrg if (expr->symtree->n.sym->ts.type != BT_DERIVED
11190 1.1 mrg && expr->symtree->n.sym->ts.type != BT_CLASS)
11191 1.1 mrg return false;
11192 1.1 mrg
11193 1.1 mrg /* Find an allocatable component ref last. */
11194 1.1 mrg for (ref = expr->ref; ref; ref = ref->next)
11195 1.1 mrg if (ref->type == REF_COMPONENT
11196 1.1 mrg && !ref->next
11197 1.1 mrg && ref->u.c.component->attr.allocatable)
11198 1.1 mrg return true;
11199 1.1 mrg
11200 1.1 mrg return false;
11201 1.1 mrg }
11202 1.1 mrg
11203 1.1 mrg
11204 1.1 mrg /* Allocate or reallocate scalar lhs, as necessary. */
11205 1.1 mrg
11206 1.1 mrg static void
11207 1.1 mrg alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
11208 1.1 mrg tree string_length,
11209 1.1 mrg gfc_expr *expr1,
11210 1.1 mrg gfc_expr *expr2)
11211 1.1 mrg
11212 1.1 mrg {
11213 1.1 mrg tree cond;
11214 1.1 mrg tree tmp;
11215 1.1 mrg tree size;
11216 1.1 mrg tree size_in_bytes;
11217 1.1 mrg tree jump_label1;
11218 1.1 mrg tree jump_label2;
11219 1.1 mrg gfc_se lse;
11220 1.1 mrg gfc_ref *ref;
11221 1.1 mrg
11222 1.1 mrg if (!expr1 || expr1->rank)
11223 1.1 mrg return;
11224 1.1 mrg
11225 1.1 mrg if (!expr2 || expr2->rank)
11226 1.1 mrg return;
11227 1.1 mrg
11228 1.1 mrg for (ref = expr1->ref; ref; ref = ref->next)
11229 1.1 mrg if (ref->type == REF_SUBSTRING)
11230 1.1 mrg return;
11231 1.1 mrg
11232 1.1 mrg realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
11233 1.1 mrg
11234 1.1 mrg /* Since this is a scalar lhs, we can afford to do this. That is,
11235 1.1 mrg there is no risk of side effects being repeated. */
11236 1.1 mrg gfc_init_se (&lse, NULL);
11237 1.1 mrg lse.want_pointer = 1;
11238 1.1 mrg gfc_conv_expr (&lse, expr1);
11239 1.1 mrg
11240 1.1 mrg jump_label1 = gfc_build_label_decl (NULL_TREE);
11241 1.1 mrg jump_label2 = gfc_build_label_decl (NULL_TREE);
11242 1.1 mrg
11243 1.1 mrg /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
11244 1.1 mrg tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
11245 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
11246 1.1 mrg lse.expr, tmp);
11247 1.1 mrg tmp = build3_v (COND_EXPR, cond,
11248 1.1 mrg build1_v (GOTO_EXPR, jump_label1),
11249 1.1 mrg build_empty_stmt (input_location));
11250 1.1 mrg gfc_add_expr_to_block (block, tmp);
11251 1.1 mrg
11252 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11253 1.1 mrg {
11254 1.1 mrg /* Use the rhs string length and the lhs element size. */
11255 1.1 mrg size = string_length;
11256 1.1 mrg tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
11257 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp);
11258 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
11259 1.1 mrg TREE_TYPE (tmp), tmp,
11260 1.1 mrg fold_convert (TREE_TYPE (tmp), size));
11261 1.1 mrg }
11262 1.1 mrg else
11263 1.1 mrg {
11264 1.1 mrg /* Otherwise use the length in bytes of the rhs. */
11265 1.1 mrg size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
11266 1.1 mrg size_in_bytes = size;
11267 1.1 mrg }
11268 1.1 mrg
11269 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
11270 1.1 mrg size_in_bytes, size_one_node);
11271 1.1 mrg
11272 1.1 mrg if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
11273 1.1 mrg {
11274 1.1 mrg tree caf_decl, token;
11275 1.1 mrg gfc_se caf_se;
11276 1.1 mrg symbol_attribute attr;
11277 1.1 mrg
11278 1.1 mrg gfc_clear_attr (&attr);
11279 1.1 mrg gfc_init_se (&caf_se, NULL);
11280 1.1 mrg
11281 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (expr1);
11282 1.1 mrg gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
11283 1.1 mrg NULL);
11284 1.1 mrg gfc_add_block_to_block (block, &caf_se.pre);
11285 1.1 mrg gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
11286 1.1 mrg gfc_build_addr_expr (NULL_TREE, token),
11287 1.1 mrg NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
11288 1.1 mrg expr1, 1);
11289 1.1 mrg }
11290 1.1 mrg else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
11291 1.1 mrg {
11292 1.1 mrg tmp = build_call_expr_loc (input_location,
11293 1.1 mrg builtin_decl_explicit (BUILT_IN_CALLOC),
11294 1.1 mrg 2, build_one_cst (size_type_node),
11295 1.1 mrg size_in_bytes);
11296 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11297 1.1 mrg gfc_add_modify (block, lse.expr, tmp);
11298 1.1 mrg }
11299 1.1 mrg else
11300 1.1 mrg {
11301 1.1 mrg tmp = build_call_expr_loc (input_location,
11302 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC),
11303 1.1 mrg 1, size_in_bytes);
11304 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11305 1.1 mrg gfc_add_modify (block, lse.expr, tmp);
11306 1.1 mrg }
11307 1.1 mrg
11308 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11309 1.1 mrg {
11310 1.1 mrg /* Deferred characters need checking for lhs and rhs string
11311 1.1 mrg length. Other deferred parameter variables will have to
11312 1.1 mrg come here too. */
11313 1.1 mrg tmp = build1_v (GOTO_EXPR, jump_label2);
11314 1.1 mrg gfc_add_expr_to_block (block, tmp);
11315 1.1 mrg }
11316 1.1 mrg tmp = build1_v (LABEL_EXPR, jump_label1);
11317 1.1 mrg gfc_add_expr_to_block (block, tmp);
11318 1.1 mrg
11319 1.1 mrg /* For a deferred length character, reallocate if lengths of lhs and
11320 1.1 mrg rhs are different. */
11321 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11322 1.1 mrg {
11323 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11324 1.1 mrg lse.string_length,
11325 1.1 mrg fold_convert (TREE_TYPE (lse.string_length),
11326 1.1 mrg size));
11327 1.1 mrg /* Jump past the realloc if the lengths are the same. */
11328 1.1 mrg tmp = build3_v (COND_EXPR, cond,
11329 1.1 mrg build1_v (GOTO_EXPR, jump_label2),
11330 1.1 mrg build_empty_stmt (input_location));
11331 1.1 mrg gfc_add_expr_to_block (block, tmp);
11332 1.1 mrg tmp = build_call_expr_loc (input_location,
11333 1.1 mrg builtin_decl_explicit (BUILT_IN_REALLOC),
11334 1.1 mrg 2, fold_convert (pvoid_type_node, lse.expr),
11335 1.1 mrg size_in_bytes);
11336 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11337 1.1 mrg gfc_add_modify (block, lse.expr, tmp);
11338 1.1 mrg tmp = build1_v (LABEL_EXPR, jump_label2);
11339 1.1 mrg gfc_add_expr_to_block (block, tmp);
11340 1.1 mrg
11341 1.1 mrg /* Update the lhs character length. */
11342 1.1 mrg size = string_length;
11343 1.1 mrg gfc_add_modify (block, lse.string_length,
11344 1.1 mrg fold_convert (TREE_TYPE (lse.string_length), size));
11345 1.1 mrg }
11346 1.1 mrg }
11347 1.1 mrg
11348 1.1 mrg /* Check for assignments of the type
11349 1.1 mrg
11350 1.1 mrg a = a + 4
11351 1.1 mrg
11352 1.1 mrg to make sure we do not check for reallocation unneccessarily. */
11353 1.1 mrg
11354 1.1 mrg
11355 1.1 mrg static bool
11356 1.1 mrg is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
11357 1.1 mrg {
11358 1.1 mrg gfc_actual_arglist *a;
11359 1.1 mrg gfc_expr *e1, *e2;
11360 1.1 mrg
11361 1.1 mrg switch (expr2->expr_type)
11362 1.1 mrg {
11363 1.1 mrg case EXPR_VARIABLE:
11364 1.1 mrg return gfc_dep_compare_expr (expr1, expr2) == 0;
11365 1.1 mrg
11366 1.1 mrg case EXPR_FUNCTION:
11367 1.1 mrg if (expr2->value.function.esym
11368 1.1 mrg && expr2->value.function.esym->attr.elemental)
11369 1.1 mrg {
11370 1.1 mrg for (a = expr2->value.function.actual; a != NULL; a = a->next)
11371 1.1 mrg {
11372 1.1 mrg e1 = a->expr;
11373 1.1 mrg if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11374 1.1 mrg return false;
11375 1.1 mrg }
11376 1.1 mrg return true;
11377 1.1 mrg }
11378 1.1 mrg else if (expr2->value.function.isym
11379 1.1 mrg && expr2->value.function.isym->elemental)
11380 1.1 mrg {
11381 1.1 mrg for (a = expr2->value.function.actual; a != NULL; a = a->next)
11382 1.1 mrg {
11383 1.1 mrg e1 = a->expr;
11384 1.1 mrg if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11385 1.1 mrg return false;
11386 1.1 mrg }
11387 1.1 mrg return true;
11388 1.1 mrg }
11389 1.1 mrg
11390 1.1 mrg break;
11391 1.1 mrg
11392 1.1 mrg case EXPR_OP:
11393 1.1 mrg switch (expr2->value.op.op)
11394 1.1 mrg {
11395 1.1 mrg case INTRINSIC_NOT:
11396 1.1 mrg case INTRINSIC_UPLUS:
11397 1.1 mrg case INTRINSIC_UMINUS:
11398 1.1 mrg case INTRINSIC_PARENTHESES:
11399 1.1 mrg return is_runtime_conformable (expr1, expr2->value.op.op1);
11400 1.1 mrg
11401 1.1 mrg case INTRINSIC_PLUS:
11402 1.1 mrg case INTRINSIC_MINUS:
11403 1.1 mrg case INTRINSIC_TIMES:
11404 1.1 mrg case INTRINSIC_DIVIDE:
11405 1.1 mrg case INTRINSIC_POWER:
11406 1.1 mrg case INTRINSIC_AND:
11407 1.1 mrg case INTRINSIC_OR:
11408 1.1 mrg case INTRINSIC_EQV:
11409 1.1 mrg case INTRINSIC_NEQV:
11410 1.1 mrg case INTRINSIC_EQ:
11411 1.1 mrg case INTRINSIC_NE:
11412 1.1 mrg case INTRINSIC_GT:
11413 1.1 mrg case INTRINSIC_GE:
11414 1.1 mrg case INTRINSIC_LT:
11415 1.1 mrg case INTRINSIC_LE:
11416 1.1 mrg case INTRINSIC_EQ_OS:
11417 1.1 mrg case INTRINSIC_NE_OS:
11418 1.1 mrg case INTRINSIC_GT_OS:
11419 1.1 mrg case INTRINSIC_GE_OS:
11420 1.1 mrg case INTRINSIC_LT_OS:
11421 1.1 mrg case INTRINSIC_LE_OS:
11422 1.1 mrg
11423 1.1 mrg e1 = expr2->value.op.op1;
11424 1.1 mrg e2 = expr2->value.op.op2;
11425 1.1 mrg
11426 1.1 mrg if (e1->rank == 0 && e2->rank > 0)
11427 1.1 mrg return is_runtime_conformable (expr1, e2);
11428 1.1 mrg else if (e1->rank > 0 && e2->rank == 0)
11429 1.1 mrg return is_runtime_conformable (expr1, e1);
11430 1.1 mrg else if (e1->rank > 0 && e2->rank > 0)
11431 1.1 mrg return is_runtime_conformable (expr1, e1)
11432 1.1 mrg && is_runtime_conformable (expr1, e2);
11433 1.1 mrg break;
11434 1.1 mrg
11435 1.1 mrg default:
11436 1.1 mrg break;
11437 1.1 mrg
11438 1.1 mrg }
11439 1.1 mrg
11440 1.1 mrg break;
11441 1.1 mrg
11442 1.1 mrg default:
11443 1.1 mrg break;
11444 1.1 mrg }
11445 1.1 mrg return false;
11446 1.1 mrg }
11447 1.1 mrg
11448 1.1 mrg
11449 1.1 mrg static tree
11450 1.1 mrg trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
11451 1.1 mrg gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11452 1.1 mrg bool class_realloc)
11453 1.1 mrg {
11454 1.1 mrg tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
11455 1.1 mrg vec<tree, va_gc> *args = NULL;
11456 1.1 mrg
11457 1.1 mrg /* Store the old vptr so that dynamic types can be compared for
11458 1.1 mrg reallocation to occur or not. */
11459 1.1 mrg if (class_realloc)
11460 1.1 mrg {
11461 1.1 mrg tmp = lse->expr;
11462 1.1 mrg if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11463 1.1 mrg tmp = gfc_get_class_from_expr (tmp);
11464 1.1 mrg }
11465 1.1 mrg
11466 1.1 mrg vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
11467 1.1 mrg &from_len);
11468 1.1 mrg
11469 1.1 mrg /* Generate (re)allocation of the lhs. */
11470 1.1 mrg if (class_realloc)
11471 1.1 mrg {
11472 1.1 mrg stmtblock_t alloc, re_alloc;
11473 1.1 mrg tree class_han, re, size;
11474 1.1 mrg
11475 1.1 mrg if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11476 1.1 mrg old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11477 1.1 mrg else
11478 1.1 mrg old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11479 1.1 mrg
11480 1.1 mrg size = gfc_vptr_size_get (vptr);
11481 1.1 mrg class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11482 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr;
11483 1.1 mrg
11484 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (class_han)))
11485 1.1 mrg class_han = gfc_build_addr_expr (NULL_TREE, class_han);
11486 1.1 mrg
11487 1.1 mrg /* Allocate block. */
11488 1.1 mrg gfc_init_block (&alloc);
11489 1.1 mrg gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11490 1.1 mrg
11491 1.1 mrg /* Reallocate if dynamic types are different. */
11492 1.1 mrg gfc_init_block (&re_alloc);
11493 1.1 mrg re = build_call_expr_loc (input_location,
11494 1.1 mrg builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11495 1.1 mrg fold_convert (pvoid_type_node, class_han),
11496 1.1 mrg size);
11497 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR,
11498 1.1 mrg logical_type_node, vptr, old_vptr);
11499 1.1 mrg re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11500 1.1 mrg tmp, re, build_empty_stmt (input_location));
11501 1.1 mrg gfc_add_expr_to_block (&re_alloc, re);
11502 1.1 mrg
11503 1.1 mrg /* Allocate if _data is NULL, reallocate otherwise. */
11504 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR,
11505 1.1 mrg logical_type_node, class_han,
11506 1.1 mrg build_int_cst (prvoid_type_node, 0));
11507 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11508 1.1 mrg gfc_unlikely (tmp,
11509 1.1 mrg PRED_FORTRAN_FAIL_ALLOC),
11510 1.1 mrg gfc_finish_block (&alloc),
11511 1.1 mrg gfc_finish_block (&re_alloc));
11512 1.1 mrg gfc_add_expr_to_block (&lse->pre, tmp);
11513 1.1 mrg }
11514 1.1 mrg
11515 1.1 mrg fcn = gfc_vptr_copy_get (vptr);
11516 1.1 mrg
11517 1.1 mrg tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11518 1.1 mrg ? gfc_class_data_get (rse->expr) : rse->expr;
11519 1.1 mrg if (use_vptr_copy)
11520 1.1 mrg {
11521 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11522 1.1 mrg || INDIRECT_REF_P (tmp)
11523 1.1 mrg || (rhs->ts.type == BT_DERIVED
11524 1.1 mrg && rhs->ts.u.derived->attr.unlimited_polymorphic
11525 1.1 mrg && !rhs->ts.u.derived->attr.pointer
11526 1.1 mrg && !rhs->ts.u.derived->attr.allocatable)
11527 1.1 mrg || (UNLIMITED_POLY (rhs)
11528 1.1 mrg && !CLASS_DATA (rhs)->attr.pointer
11529 1.1 mrg && !CLASS_DATA (rhs)->attr.allocatable))
11530 1.1 mrg vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11531 1.1 mrg else
11532 1.1 mrg vec_safe_push (args, tmp);
11533 1.1 mrg tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11534 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr;
11535 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11536 1.1 mrg || INDIRECT_REF_P (tmp)
11537 1.1 mrg || (lhs->ts.type == BT_DERIVED
11538 1.1 mrg && lhs->ts.u.derived->attr.unlimited_polymorphic
11539 1.1 mrg && !lhs->ts.u.derived->attr.pointer
11540 1.1 mrg && !lhs->ts.u.derived->attr.allocatable)
11541 1.1 mrg || (UNLIMITED_POLY (lhs)
11542 1.1 mrg && !CLASS_DATA (lhs)->attr.pointer
11543 1.1 mrg && !CLASS_DATA (lhs)->attr.allocatable))
11544 1.1 mrg vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11545 1.1 mrg else
11546 1.1 mrg vec_safe_push (args, tmp);
11547 1.1 mrg
11548 1.1 mrg stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11549 1.1 mrg
11550 1.1 mrg if (to_len != NULL_TREE && !integer_zerop (from_len))
11551 1.1 mrg {
11552 1.1 mrg tree extcopy;
11553 1.1 mrg vec_safe_push (args, from_len);
11554 1.1 mrg vec_safe_push (args, to_len);
11555 1.1 mrg extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11556 1.1 mrg
11557 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR,
11558 1.1 mrg logical_type_node, from_len,
11559 1.1 mrg build_zero_cst (TREE_TYPE (from_len)));
11560 1.1 mrg return fold_build3_loc (input_location, COND_EXPR,
11561 1.1 mrg void_type_node, tmp,
11562 1.1 mrg extcopy, stdcopy);
11563 1.1 mrg }
11564 1.1 mrg else
11565 1.1 mrg return stdcopy;
11566 1.1 mrg }
11567 1.1 mrg else
11568 1.1 mrg {
11569 1.1 mrg tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11570 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr;
11571 1.1 mrg stmtblock_t tblock;
11572 1.1 mrg gfc_init_block (&tblock);
11573 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11574 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11575 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11576 1.1 mrg rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11577 1.1 mrg /* When coming from a ptr_copy lhs and rhs are swapped. */
11578 1.1 mrg gfc_add_modify_loc (input_location, &tblock, rhst,
11579 1.1 mrg fold_convert (TREE_TYPE (rhst), tmp));
11580 1.1 mrg return gfc_finish_block (&tblock);
11581 1.1 mrg }
11582 1.1 mrg }
11583 1.1 mrg
11584 1.1 mrg /* Subroutine of gfc_trans_assignment that actually scalarizes the
11585 1.1 mrg assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11586 1.1 mrg init_flag indicates initialization expressions and dealloc that no
11587 1.1 mrg deallocate prior assignment is needed (if in doubt, set true).
11588 1.1 mrg When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11589 1.1 mrg routine instead of a pointer assignment. Alias resolution is only done,
11590 1.1 mrg when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11591 1.1 mrg where it is known, that newly allocated memory on the lhs can never be
11592 1.1 mrg an alias of the rhs. */
11593 1.1 mrg
11594 1.1 mrg static tree
11595 1.1 mrg gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11596 1.1 mrg bool dealloc, bool use_vptr_copy, bool may_alias)
11597 1.1 mrg {
11598 1.1 mrg gfc_se lse;
11599 1.1 mrg gfc_se rse;
11600 1.1 mrg gfc_ss *lss;
11601 1.1 mrg gfc_ss *lss_section;
11602 1.1 mrg gfc_ss *rss;
11603 1.1 mrg gfc_loopinfo loop;
11604 1.1 mrg tree tmp;
11605 1.1 mrg stmtblock_t block;
11606 1.1 mrg stmtblock_t body;
11607 1.1 mrg bool l_is_temp;
11608 1.1 mrg bool scalar_to_array;
11609 1.1 mrg tree string_length;
11610 1.1 mrg int n;
11611 1.1 mrg bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
11612 1.1 mrg symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
11613 1.1 mrg bool is_poly_assign;
11614 1.1 mrg bool realloc_flag;
11615 1.1 mrg
11616 1.1 mrg /* Assignment of the form lhs = rhs. */
11617 1.1 mrg gfc_start_block (&block);
11618 1.1 mrg
11619 1.1 mrg gfc_init_se (&lse, NULL);
11620 1.1 mrg gfc_init_se (&rse, NULL);
11621 1.1 mrg
11622 1.1 mrg /* Walk the lhs. */
11623 1.1 mrg lss = gfc_walk_expr (expr1);
11624 1.1 mrg if (gfc_is_reallocatable_lhs (expr1))
11625 1.1 mrg {
11626 1.1 mrg lss->no_bounds_check = 1;
11627 1.1 mrg if (!(expr2->expr_type == EXPR_FUNCTION
11628 1.1 mrg && expr2->value.function.isym != NULL
11629 1.1 mrg && !(expr2->value.function.isym->elemental
11630 1.1 mrg || expr2->value.function.isym->conversion)))
11631 1.1 mrg lss->is_alloc_lhs = 1;
11632 1.1 mrg }
11633 1.1 mrg else
11634 1.1 mrg lss->no_bounds_check = expr1->no_bounds_check;
11635 1.1 mrg
11636 1.1 mrg rss = NULL;
11637 1.1 mrg
11638 1.1 mrg if ((expr1->ts.type == BT_DERIVED)
11639 1.1 mrg && (gfc_is_class_array_function (expr2)
11640 1.1 mrg || gfc_is_alloc_class_scalar_function (expr2)))
11641 1.1 mrg expr2->must_finalize = 1;
11642 1.1 mrg
11643 1.1 mrg /* Checking whether a class assignment is desired is quite complicated and
11644 1.1 mrg needed at two locations, so do it once only before the information is
11645 1.1 mrg needed. */
11646 1.1 mrg lhs_attr = gfc_expr_attr (expr1);
11647 1.1 mrg is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11648 1.1 mrg || (lhs_attr.allocatable && !lhs_attr.dimension))
11649 1.1 mrg && (expr1->ts.type == BT_CLASS
11650 1.1 mrg || gfc_is_class_array_ref (expr1, NULL)
11651 1.1 mrg || gfc_is_class_scalar_expr (expr1)
11652 1.1 mrg || gfc_is_class_array_ref (expr2, NULL)
11653 1.1 mrg || gfc_is_class_scalar_expr (expr2))
11654 1.1 mrg && lhs_attr.flavor != FL_PROCEDURE;
11655 1.1 mrg
11656 1.1 mrg realloc_flag = flag_realloc_lhs
11657 1.1 mrg && gfc_is_reallocatable_lhs (expr1)
11658 1.1 mrg && expr2->rank
11659 1.1 mrg && !is_runtime_conformable (expr1, expr2);
11660 1.1 mrg
11661 1.1 mrg /* Only analyze the expressions for coarray properties, when in coarray-lib
11662 1.1 mrg mode. */
11663 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
11664 1.1 mrg {
11665 1.1 mrg lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
11666 1.1 mrg rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
11667 1.1 mrg }
11668 1.1 mrg
11669 1.1 mrg if (lss != gfc_ss_terminator)
11670 1.1 mrg {
11671 1.1 mrg /* The assignment needs scalarization. */
11672 1.1 mrg lss_section = lss;
11673 1.1 mrg
11674 1.1 mrg /* Find a non-scalar SS from the lhs. */
11675 1.1 mrg while (lss_section != gfc_ss_terminator
11676 1.1 mrg && lss_section->info->type != GFC_SS_SECTION)
11677 1.1 mrg lss_section = lss_section->next;
11678 1.1 mrg
11679 1.1 mrg gcc_assert (lss_section != gfc_ss_terminator);
11680 1.1 mrg
11681 1.1 mrg /* Initialize the scalarizer. */
11682 1.1 mrg gfc_init_loopinfo (&loop);
11683 1.1 mrg
11684 1.1 mrg /* Walk the rhs. */
11685 1.1 mrg rss = gfc_walk_expr (expr2);
11686 1.1 mrg if (rss == gfc_ss_terminator)
11687 1.1 mrg /* The rhs is scalar. Add a ss for the expression. */
11688 1.1 mrg rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
11689 1.1 mrg /* When doing a class assign, then the handle to the rhs needs to be a
11690 1.1 mrg pointer to allow for polymorphism. */
11691 1.1 mrg if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
11692 1.1 mrg rss->info->type = GFC_SS_REFERENCE;
11693 1.1 mrg
11694 1.1 mrg rss->no_bounds_check = expr2->no_bounds_check;
11695 1.1 mrg /* Associate the SS with the loop. */
11696 1.1 mrg gfc_add_ss_to_loop (&loop, lss);
11697 1.1 mrg gfc_add_ss_to_loop (&loop, rss);
11698 1.1 mrg
11699 1.1 mrg /* Calculate the bounds of the scalarization. */
11700 1.1 mrg gfc_conv_ss_startstride (&loop);
11701 1.1 mrg /* Enable loop reversal. */
11702 1.1 mrg for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
11703 1.1 mrg loop.reverse[n] = GFC_ENABLE_REVERSE;
11704 1.1 mrg /* Resolve any data dependencies in the statement. */
11705 1.1 mrg if (may_alias)
11706 1.1 mrg gfc_conv_resolve_dependencies (&loop, lss, rss);
11707 1.1 mrg /* Setup the scalarizing loops. */
11708 1.1 mrg gfc_conv_loop_setup (&loop, &expr2->where);
11709 1.1 mrg
11710 1.1 mrg /* Setup the gfc_se structures. */
11711 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop);
11712 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop);
11713 1.1 mrg
11714 1.1 mrg rse.ss = rss;
11715 1.1 mrg gfc_mark_ss_chain_used (rss, 1);
11716 1.1 mrg if (loop.temp_ss == NULL)
11717 1.1 mrg {
11718 1.1 mrg lse.ss = lss;
11719 1.1 mrg gfc_mark_ss_chain_used (lss, 1);
11720 1.1 mrg }
11721 1.1 mrg else
11722 1.1 mrg {
11723 1.1 mrg lse.ss = loop.temp_ss;
11724 1.1 mrg gfc_mark_ss_chain_used (lss, 3);
11725 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 3);
11726 1.1 mrg }
11727 1.1 mrg
11728 1.1 mrg /* Allow the scalarizer to workshare array assignments. */
11729 1.1 mrg if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
11730 1.1 mrg == OMPWS_WORKSHARE_FLAG
11731 1.1 mrg && loop.temp_ss == NULL)
11732 1.1 mrg {
11733 1.1 mrg maybe_workshare = true;
11734 1.1 mrg ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
11735 1.1 mrg }
11736 1.1 mrg
11737 1.1 mrg /* Start the scalarized loop body. */
11738 1.1 mrg gfc_start_scalarized_body (&loop, &body);
11739 1.1 mrg }
11740 1.1 mrg else
11741 1.1 mrg gfc_init_block (&body);
11742 1.1 mrg
11743 1.1 mrg l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
11744 1.1 mrg
11745 1.1 mrg /* Translate the expression. */
11746 1.1 mrg rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
11747 1.1 mrg && lhs_caf_attr.codimension;
11748 1.1 mrg gfc_conv_expr (&rse, expr2);
11749 1.1 mrg
11750 1.1 mrg /* Deal with the case of a scalar class function assigned to a derived type. */
11751 1.1 mrg if (gfc_is_alloc_class_scalar_function (expr2)
11752 1.1 mrg && expr1->ts.type == BT_DERIVED)
11753 1.1 mrg {
11754 1.1 mrg rse.expr = gfc_class_data_get (rse.expr);
11755 1.1 mrg rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
11756 1.1 mrg }
11757 1.1 mrg
11758 1.1 mrg /* Stabilize a string length for temporaries. */
11759 1.1 mrg if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
11760 1.1 mrg && !(VAR_P (rse.string_length)
11761 1.1 mrg || TREE_CODE (rse.string_length) == PARM_DECL
11762 1.1 mrg || TREE_CODE (rse.string_length) == INDIRECT_REF))
11763 1.1 mrg string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
11764 1.1 mrg else if (expr2->ts.type == BT_CHARACTER)
11765 1.1 mrg {
11766 1.1 mrg if (expr1->ts.deferred
11767 1.1 mrg && gfc_expr_attr (expr1).allocatable
11768 1.1 mrg && gfc_check_dependency (expr1, expr2, true))
11769 1.1 mrg rse.string_length =
11770 1.1 mrg gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
11771 1.1 mrg string_length = rse.string_length;
11772 1.1 mrg }
11773 1.1 mrg else
11774 1.1 mrg string_length = NULL_TREE;
11775 1.1 mrg
11776 1.1 mrg if (l_is_temp)
11777 1.1 mrg {
11778 1.1 mrg gfc_conv_tmp_array_ref (&lse);
11779 1.1 mrg if (expr2->ts.type == BT_CHARACTER)
11780 1.1 mrg lse.string_length = string_length;
11781 1.1 mrg }
11782 1.1 mrg else
11783 1.1 mrg {
11784 1.1 mrg gfc_conv_expr (&lse, expr1);
11785 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_MEM
11786 1.1 mrg && !init_flag
11787 1.1 mrg && gfc_expr_attr (expr1).allocatable
11788 1.1 mrg && expr1->rank
11789 1.1 mrg && !expr2->rank)
11790 1.1 mrg {
11791 1.1 mrg tree cond;
11792 1.1 mrg const char* msg;
11793 1.1 mrg
11794 1.1 mrg tmp = INDIRECT_REF_P (lse.expr)
11795 1.1 mrg ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
11796 1.1 mrg STRIP_NOPS (tmp);
11797 1.1 mrg
11798 1.1 mrg /* We should only get array references here. */
11799 1.1 mrg gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
11800 1.1 mrg || TREE_CODE (tmp) == ARRAY_REF);
11801 1.1 mrg
11802 1.1 mrg /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11803 1.1 mrg or the array itself(ARRAY_REF). */
11804 1.1 mrg tmp = TREE_OPERAND (tmp, 0);
11805 1.1 mrg
11806 1.1 mrg /* Provide the address of the array. */
11807 1.1 mrg if (TREE_CODE (lse.expr) == ARRAY_REF)
11808 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11809 1.1 mrg
11810 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11811 1.1 mrg tmp, build_int_cst (TREE_TYPE (tmp), 0));
11812 1.1 mrg msg = _("Assignment of scalar to unallocated array");
11813 1.1 mrg gfc_trans_runtime_check (true, false, cond, &loop.pre,
11814 1.1 mrg &expr1->where, msg);
11815 1.1 mrg }
11816 1.1 mrg
11817 1.1 mrg /* Deallocate the lhs parameterized components if required. */
11818 1.1 mrg if (dealloc && expr2->expr_type == EXPR_FUNCTION
11819 1.1 mrg && !expr1->symtree->n.sym->attr.associate_var)
11820 1.1 mrg {
11821 1.1 mrg if (expr1->ts.type == BT_DERIVED
11822 1.1 mrg && expr1->ts.u.derived
11823 1.1 mrg && expr1->ts.u.derived->attr.pdt_type)
11824 1.1 mrg {
11825 1.1 mrg tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
11826 1.1 mrg expr1->rank);
11827 1.1 mrg gfc_add_expr_to_block (&lse.pre, tmp);
11828 1.1 mrg }
11829 1.1 mrg else if (expr1->ts.type == BT_CLASS
11830 1.1 mrg && CLASS_DATA (expr1)->ts.u.derived
11831 1.1 mrg && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
11832 1.1 mrg {
11833 1.1 mrg tmp = gfc_class_data_get (lse.expr);
11834 1.1 mrg tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
11835 1.1 mrg tmp, expr1->rank);
11836 1.1 mrg gfc_add_expr_to_block (&lse.pre, tmp);
11837 1.1 mrg }
11838 1.1 mrg }
11839 1.1 mrg }
11840 1.1 mrg
11841 1.1 mrg /* Assignments of scalar derived types with allocatable components
11842 1.1 mrg to arrays must be done with a deep copy and the rhs temporary
11843 1.1 mrg must have its components deallocated afterwards. */
11844 1.1 mrg scalar_to_array = (expr2->ts.type == BT_DERIVED
11845 1.1 mrg && expr2->ts.u.derived->attr.alloc_comp
11846 1.1 mrg && !gfc_expr_is_variable (expr2)
11847 1.1 mrg && expr1->rank && !expr2->rank);
11848 1.1 mrg scalar_to_array |= (expr1->ts.type == BT_DERIVED
11849 1.1 mrg && expr1->rank
11850 1.1 mrg && expr1->ts.u.derived->attr.alloc_comp
11851 1.1 mrg && gfc_is_alloc_class_scalar_function (expr2));
11852 1.1 mrg if (scalar_to_array && dealloc)
11853 1.1 mrg {
11854 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
11855 1.1 mrg gfc_prepend_expr_to_block (&loop.post, tmp);
11856 1.1 mrg }
11857 1.1 mrg
11858 1.1 mrg /* When assigning a character function result to a deferred-length variable,
11859 1.1 mrg the function call must happen before the (re)allocation of the lhs -
11860 1.1 mrg otherwise the character length of the result is not known.
11861 1.1 mrg NOTE 1: This relies on having the exact dependence of the length type
11862 1.1 mrg parameter available to the caller; gfortran saves it in the .mod files.
11863 1.1 mrg NOTE 2: Vector array references generate an index temporary that must
11864 1.1 mrg not go outside the loop. Otherwise, variables should not generate
11865 1.1 mrg a pre block.
11866 1.1 mrg NOTE 3: The concatenation operation generates a temporary pointer,
11867 1.1 mrg whose allocation must go to the innermost loop.
11868 1.1 mrg NOTE 4: Elemental functions may generate a temporary, too. */
11869 1.1 mrg if (flag_realloc_lhs
11870 1.1 mrg && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
11871 1.1 mrg && !(lss != gfc_ss_terminator
11872 1.1 mrg && rss != gfc_ss_terminator
11873 1.1 mrg && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
11874 1.1 mrg || (expr2->expr_type == EXPR_FUNCTION
11875 1.1 mrg && expr2->value.function.esym != NULL
11876 1.1 mrg && expr2->value.function.esym->attr.elemental)
11877 1.1 mrg || (expr2->expr_type == EXPR_FUNCTION
11878 1.1 mrg && expr2->value.function.isym != NULL
11879 1.1 mrg && expr2->value.function.isym->elemental)
11880 1.1 mrg || (expr2->expr_type == EXPR_OP
11881 1.1 mrg && expr2->value.op.op == INTRINSIC_CONCAT))))
11882 1.1 mrg gfc_add_block_to_block (&block, &rse.pre);
11883 1.1 mrg
11884 1.1 mrg /* Nullify the allocatable components corresponding to those of the lhs
11885 1.1 mrg derived type, so that the finalization of the function result does not
11886 1.1 mrg affect the lhs of the assignment. Prepend is used to ensure that the
11887 1.1 mrg nullification occurs before the call to the finalizer. In the case of
11888 1.1 mrg a scalar to array assignment, this is done in gfc_trans_scalar_assign
11889 1.1 mrg as part of the deep copy. */
11890 1.1 mrg if (!scalar_to_array && expr1->ts.type == BT_DERIVED
11891 1.1 mrg && (gfc_is_class_array_function (expr2)
11892 1.1 mrg || gfc_is_alloc_class_scalar_function (expr2)))
11893 1.1 mrg {
11894 1.1 mrg tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
11895 1.1 mrg gfc_prepend_expr_to_block (&rse.post, tmp);
11896 1.1 mrg if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
11897 1.1 mrg gfc_add_block_to_block (&loop.post, &rse.post);
11898 1.1 mrg }
11899 1.1 mrg
11900 1.1 mrg tmp = NULL_TREE;
11901 1.1 mrg
11902 1.1 mrg if (is_poly_assign)
11903 1.1 mrg {
11904 1.1 mrg tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
11905 1.1 mrg use_vptr_copy || (lhs_attr.allocatable
11906 1.1 mrg && !lhs_attr.dimension),
11907 1.1 mrg !realloc_flag && flag_realloc_lhs
11908 1.1 mrg && !lhs_attr.pointer);
11909 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION
11910 1.1 mrg && expr2->ts.type == BT_DERIVED
11911 1.1 mrg && expr2->ts.u.derived->attr.alloc_comp)
11912 1.1 mrg {
11913 1.1 mrg tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
11914 1.1 mrg rse.expr, expr2->rank);
11915 1.1 mrg if (lss == gfc_ss_terminator)
11916 1.1 mrg gfc_add_expr_to_block (&rse.post, tmp2);
11917 1.1 mrg else
11918 1.1 mrg gfc_add_expr_to_block (&loop.post, tmp2);
11919 1.1 mrg }
11920 1.1 mrg }
11921 1.1 mrg else if (flag_coarray == GFC_FCOARRAY_LIB
11922 1.1 mrg && lhs_caf_attr.codimension && rhs_caf_attr.codimension
11923 1.1 mrg && ((lhs_caf_attr.allocatable && lhs_refs_comp)
11924 1.1 mrg || (rhs_caf_attr.allocatable && rhs_refs_comp)))
11925 1.1 mrg {
11926 1.1 mrg /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11927 1.1 mrg allocatable component, because those need to be accessed via the
11928 1.1 mrg caf-runtime. No need to check for coindexes here, because resolve
11929 1.1 mrg has rewritten those already. */
11930 1.1 mrg gfc_code code;
11931 1.1 mrg gfc_actual_arglist a1, a2;
11932 1.1 mrg /* Clear the structures to prevent accessing garbage. */
11933 1.1 mrg memset (&code, '\0', sizeof (gfc_code));
11934 1.1 mrg memset (&a1, '\0', sizeof (gfc_actual_arglist));
11935 1.1 mrg memset (&a2, '\0', sizeof (gfc_actual_arglist));
11936 1.1 mrg a1.expr = expr1;
11937 1.1 mrg a1.next = &a2;
11938 1.1 mrg a2.expr = expr2;
11939 1.1 mrg a2.next = NULL;
11940 1.1 mrg code.ext.actual = &a1;
11941 1.1 mrg code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
11942 1.1 mrg tmp = gfc_conv_intrinsic_subroutine (&code);
11943 1.1 mrg }
11944 1.1 mrg else if (!is_poly_assign && expr2->must_finalize
11945 1.1 mrg && expr1->ts.type == BT_CLASS
11946 1.1 mrg && expr2->ts.type == BT_CLASS)
11947 1.1 mrg {
11948 1.1 mrg /* This case comes about when the scalarizer provides array element
11949 1.1 mrg references. Use the vptr copy function, since this does a deep
11950 1.1 mrg copy of allocatable components, without which the finalizer call
11951 1.1 mrg will deallocate the components. */
11952 1.1 mrg tmp = gfc_get_vptr_from_expr (rse.expr);
11953 1.1 mrg if (tmp != NULL_TREE)
11954 1.1 mrg {
11955 1.1 mrg tree fcn = gfc_vptr_copy_get (tmp);
11956 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (fcn)))
11957 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn);
11958 1.1 mrg tmp = build_call_expr_loc (input_location,
11959 1.1 mrg fcn, 2,
11960 1.1 mrg gfc_build_addr_expr (NULL, rse.expr),
11961 1.1 mrg gfc_build_addr_expr (NULL, lse.expr));
11962 1.1 mrg }
11963 1.1 mrg }
11964 1.1 mrg
11965 1.1 mrg /* If nothing else works, do it the old fashioned way! */
11966 1.1 mrg if (tmp == NULL_TREE)
11967 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11968 1.1 mrg gfc_expr_is_variable (expr2)
11969 1.1 mrg || scalar_to_array
11970 1.1 mrg || expr2->expr_type == EXPR_ARRAY,
11971 1.1 mrg !(l_is_temp || init_flag) && dealloc,
11972 1.1 mrg expr1->symtree->n.sym->attr.codimension);
11973 1.1 mrg
11974 1.1 mrg /* Add the pre blocks to the body. */
11975 1.1 mrg gfc_add_block_to_block (&body, &rse.pre);
11976 1.1 mrg gfc_add_block_to_block (&body, &lse.pre);
11977 1.1 mrg gfc_add_expr_to_block (&body, tmp);
11978 1.1 mrg /* Add the post blocks to the body. */
11979 1.1 mrg gfc_add_block_to_block (&body, &rse.post);
11980 1.1 mrg gfc_add_block_to_block (&body, &lse.post);
11981 1.1 mrg
11982 1.1 mrg if (lss == gfc_ss_terminator)
11983 1.1 mrg {
11984 1.1 mrg /* F2003: Add the code for reallocation on assignment. */
11985 1.1 mrg if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
11986 1.1 mrg && !is_poly_assign)
11987 1.1 mrg alloc_scalar_allocatable_for_assignment (&block, string_length,
11988 1.1 mrg expr1, expr2);
11989 1.1 mrg
11990 1.1 mrg /* Use the scalar assignment as is. */
11991 1.1 mrg gfc_add_block_to_block (&block, &body);
11992 1.1 mrg }
11993 1.1 mrg else
11994 1.1 mrg {
11995 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator
11996 1.1 mrg && rse.ss == gfc_ss_terminator);
11997 1.1 mrg
11998 1.1 mrg if (l_is_temp)
11999 1.1 mrg {
12000 1.1 mrg gfc_trans_scalarized_loop_boundary (&loop, &body);
12001 1.1 mrg
12002 1.1 mrg /* We need to copy the temporary to the actual lhs. */
12003 1.1 mrg gfc_init_se (&lse, NULL);
12004 1.1 mrg gfc_init_se (&rse, NULL);
12005 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop);
12006 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop);
12007 1.1 mrg
12008 1.1 mrg rse.ss = loop.temp_ss;
12009 1.1 mrg lse.ss = lss;
12010 1.1 mrg
12011 1.1 mrg gfc_conv_tmp_array_ref (&rse);
12012 1.1 mrg gfc_conv_expr (&lse, expr1);
12013 1.1 mrg
12014 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator
12015 1.1 mrg && rse.ss == gfc_ss_terminator);
12016 1.1 mrg
12017 1.1 mrg if (expr2->ts.type == BT_CHARACTER)
12018 1.1 mrg rse.string_length = string_length;
12019 1.1 mrg
12020 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
12021 1.1 mrg false, dealloc);
12022 1.1 mrg gfc_add_expr_to_block (&body, tmp);
12023 1.1 mrg }
12024 1.1 mrg
12025 1.1 mrg /* F2003: Allocate or reallocate lhs of allocatable array. */
12026 1.1 mrg if (realloc_flag)
12027 1.1 mrg {
12028 1.1 mrg realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
12029 1.1 mrg ompws_flags &= ~OMPWS_SCALARIZER_WS;
12030 1.1 mrg tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
12031 1.1 mrg if (tmp != NULL_TREE)
12032 1.1 mrg gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
12033 1.1 mrg }
12034 1.1 mrg
12035 1.1 mrg if (maybe_workshare)
12036 1.1 mrg ompws_flags &= ~OMPWS_SCALARIZER_BODY;
12037 1.1 mrg
12038 1.1 mrg /* Generate the copying loops. */
12039 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body);
12040 1.1 mrg
12041 1.1 mrg /* Wrap the whole thing up. */
12042 1.1 mrg gfc_add_block_to_block (&block, &loop.pre);
12043 1.1 mrg gfc_add_block_to_block (&block, &loop.post);
12044 1.1 mrg
12045 1.1 mrg gfc_cleanup_loop (&loop);
12046 1.1 mrg }
12047 1.1 mrg
12048 1.1 mrg return gfc_finish_block (&block);
12049 1.1 mrg }
12050 1.1 mrg
12051 1.1 mrg
12052 1.1 mrg /* Check whether EXPR is a copyable array. */
12053 1.1 mrg
12054 1.1 mrg static bool
12055 1.1 mrg copyable_array_p (gfc_expr * expr)
12056 1.1 mrg {
12057 1.1 mrg if (expr->expr_type != EXPR_VARIABLE)
12058 1.1 mrg return false;
12059 1.1 mrg
12060 1.1 mrg /* First check it's an array. */
12061 1.1 mrg if (expr->rank < 1 || !expr->ref || expr->ref->next)
12062 1.1 mrg return false;
12063 1.1 mrg
12064 1.1 mrg if (!gfc_full_array_ref_p (expr->ref, NULL))
12065 1.1 mrg return false;
12066 1.1 mrg
12067 1.1 mrg /* Next check that it's of a simple enough type. */
12068 1.1 mrg switch (expr->ts.type)
12069 1.1 mrg {
12070 1.1 mrg case BT_INTEGER:
12071 1.1 mrg case BT_REAL:
12072 1.1 mrg case BT_COMPLEX:
12073 1.1 mrg case BT_LOGICAL:
12074 1.1 mrg return true;
12075 1.1 mrg
12076 1.1 mrg case BT_CHARACTER:
12077 1.1 mrg return false;
12078 1.1 mrg
12079 1.1 mrg case_bt_struct:
12080 1.1 mrg return !expr->ts.u.derived->attr.alloc_comp;
12081 1.1 mrg
12082 1.1 mrg default:
12083 1.1 mrg break;
12084 1.1 mrg }
12085 1.1 mrg
12086 1.1 mrg return false;
12087 1.1 mrg }
12088 1.1 mrg
12089 1.1 mrg /* Translate an assignment. */
12090 1.1 mrg
12091 1.1 mrg tree
12092 1.1 mrg gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
12093 1.1 mrg bool dealloc, bool use_vptr_copy, bool may_alias)
12094 1.1 mrg {
12095 1.1 mrg tree tmp;
12096 1.1 mrg
12097 1.1 mrg /* Special case a single function returning an array. */
12098 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
12099 1.1 mrg {
12100 1.1 mrg tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
12101 1.1 mrg if (tmp)
12102 1.1 mrg return tmp;
12103 1.1 mrg }
12104 1.1 mrg
12105 1.1 mrg /* Special case assigning an array to zero. */
12106 1.1 mrg if (copyable_array_p (expr1)
12107 1.1 mrg && is_zero_initializer_p (expr2))
12108 1.1 mrg {
12109 1.1 mrg tmp = gfc_trans_zero_assign (expr1);
12110 1.1 mrg if (tmp)
12111 1.1 mrg return tmp;
12112 1.1 mrg }
12113 1.1 mrg
12114 1.1 mrg /* Special case copying one array to another. */
12115 1.1 mrg if (copyable_array_p (expr1)
12116 1.1 mrg && copyable_array_p (expr2)
12117 1.1 mrg && gfc_compare_types (&expr1->ts, &expr2->ts)
12118 1.1 mrg && !gfc_check_dependency (expr1, expr2, 0))
12119 1.1 mrg {
12120 1.1 mrg tmp = gfc_trans_array_copy (expr1, expr2);
12121 1.1 mrg if (tmp)
12122 1.1 mrg return tmp;
12123 1.1 mrg }
12124 1.1 mrg
12125 1.1 mrg /* Special case initializing an array from a constant array constructor. */
12126 1.1 mrg if (copyable_array_p (expr1)
12127 1.1 mrg && expr2->expr_type == EXPR_ARRAY
12128 1.1 mrg && gfc_compare_types (&expr1->ts, &expr2->ts))
12129 1.1 mrg {
12130 1.1 mrg tmp = gfc_trans_array_constructor_copy (expr1, expr2);
12131 1.1 mrg if (tmp)
12132 1.1 mrg return tmp;
12133 1.1 mrg }
12134 1.1 mrg
12135 1.1 mrg if (UNLIMITED_POLY (expr1) && expr1->rank)
12136 1.1 mrg use_vptr_copy = true;
12137 1.1 mrg
12138 1.1 mrg /* Fallback to the scalarizer to generate explicit loops. */
12139 1.1 mrg return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
12140 1.1 mrg use_vptr_copy, may_alias);
12141 1.1 mrg }
12142 1.1 mrg
12143 1.1 mrg tree
12144 1.1 mrg gfc_trans_init_assign (gfc_code * code)
12145 1.1 mrg {
12146 1.1 mrg return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
12147 1.1 mrg }
12148 1.1 mrg
12149 1.1 mrg tree
12150 1.1 mrg gfc_trans_assign (gfc_code * code)
12151 1.1 mrg {
12152 1.1 mrg return gfc_trans_assignment (code->expr1, code->expr2, false, true);
12153 1.1 mrg }
12154 1.1 mrg
12155 1.1 mrg /* Generate a simple loop for internal use of the form
12156 1.1 mrg for (var = begin; var <cond> end; var += step)
12157 1.1 mrg body; */
12158 1.1 mrg void
12159 1.1 mrg gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end,
12160 1.1 mrg enum tree_code cond, tree step, tree body)
12161 1.1 mrg {
12162 1.1 mrg tree tmp;
12163 1.1 mrg
12164 1.1 mrg /* var = begin. */
12165 1.1 mrg gfc_add_modify (block, var, begin);
12166 1.1 mrg
12167 1.1 mrg /* Loop: for (var = begin; var <cond> end; var += step). */
12168 1.1 mrg tree label_loop = gfc_build_label_decl (NULL_TREE);
12169 1.1 mrg tree label_cond = gfc_build_label_decl (NULL_TREE);
12170 1.1 mrg TREE_USED (label_loop) = 1;
12171 1.1 mrg TREE_USED (label_cond) = 1;
12172 1.1 mrg
12173 1.1 mrg gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond));
12174 1.1 mrg gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop));
12175 1.1 mrg
12176 1.1 mrg /* Loop body. */
12177 1.1 mrg gfc_add_expr_to_block (block, body);
12178 1.1 mrg
12179 1.1 mrg /* End of loop body. */
12180 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step);
12181 1.1 mrg gfc_add_modify (block, var, tmp);
12182 1.1 mrg gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond));
12183 1.1 mrg tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end);
12184 1.1 mrg tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop),
12185 1.1 mrg build_empty_stmt (input_location));
12186 1.1 mrg gfc_add_expr_to_block (block, tmp);
12187 1.1 mrg }
12188