trans.cc revision 1.1.1.1 1 1.1 mrg /* Code translation -- generate GCC trees from gfc_code.
2 1.1 mrg Copyright (C) 2002-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Paul Brook
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg #include "options.h"
25 1.1 mrg #include "tree.h"
26 1.1 mrg #include "gfortran.h"
27 1.1 mrg #include "gimple-expr.h" /* For create_tmp_var_raw. */
28 1.1 mrg #include "trans.h"
29 1.1 mrg #include "stringpool.h"
30 1.1 mrg #include "fold-const.h"
31 1.1 mrg #include "tree-iterator.h"
32 1.1 mrg #include "trans-stmt.h"
33 1.1 mrg #include "trans-array.h"
34 1.1 mrg #include "trans-types.h"
35 1.1 mrg #include "trans-const.h"
36 1.1 mrg
37 1.1 mrg /* Naming convention for backend interface code:
38 1.1 mrg
39 1.1 mrg gfc_trans_* translate gfc_code into STMT trees.
40 1.1 mrg
41 1.1 mrg gfc_conv_* expression conversion
42 1.1 mrg
43 1.1 mrg gfc_get_* get a backend tree representation of a decl or type */
44 1.1 mrg
45 1.1 mrg static gfc_file *gfc_current_backend_file;
46 1.1 mrg
47 1.1 mrg const char gfc_msg_fault[] = N_("Array reference out of bounds");
48 1.1 mrg
49 1.1 mrg
50 1.1 mrg /* Return a location_t suitable for 'tree' for a gfortran locus. The way the
51 1.1 mrg parser works in gfortran, loc->lb->location contains only the line number
52 1.1 mrg and LOCATION_COLUMN is 0; hence, the column has to be added when generating
53 1.1 mrg locations for 'tree'. Cf. error.cc's gfc_format_decoder. */
54 1.1 mrg
55 1.1 mrg location_t
56 1.1 mrg gfc_get_location (locus *loc)
57 1.1 mrg {
58 1.1 mrg return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
59 1.1 mrg loc->nextc - loc->lb->line);
60 1.1 mrg }
61 1.1 mrg
62 1.1 mrg /* Advance along TREE_CHAIN n times. */
63 1.1 mrg
64 1.1 mrg tree
65 1.1 mrg gfc_advance_chain (tree t, int n)
66 1.1 mrg {
67 1.1 mrg for (; n > 0; n--)
68 1.1 mrg {
69 1.1 mrg gcc_assert (t != NULL_TREE);
70 1.1 mrg t = DECL_CHAIN (t);
71 1.1 mrg }
72 1.1 mrg return t;
73 1.1 mrg }
74 1.1 mrg
75 1.1 mrg static int num_var;
76 1.1 mrg
77 1.1 mrg #define MAX_PREFIX_LEN 20
78 1.1 mrg
79 1.1 mrg static tree
80 1.1 mrg create_var_debug_raw (tree type, const char *prefix)
81 1.1 mrg {
82 1.1 mrg /* Space for prefix + "_" + 10-digit-number + \0. */
83 1.1 mrg char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
84 1.1 mrg tree t;
85 1.1 mrg int i;
86 1.1 mrg
87 1.1 mrg if (prefix == NULL)
88 1.1 mrg prefix = "gfc";
89 1.1 mrg else
90 1.1 mrg gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
91 1.1 mrg
92 1.1 mrg for (i = 0; prefix[i] != 0; i++)
93 1.1 mrg name_buf[i] = gfc_wide_toupper (prefix[i]);
94 1.1 mrg
95 1.1 mrg snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
96 1.1 mrg
97 1.1 mrg t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
98 1.1 mrg
99 1.1 mrg /* Not setting this causes some regressions. */
100 1.1 mrg DECL_ARTIFICIAL (t) = 1;
101 1.1 mrg
102 1.1 mrg /* We want debug info for it. */
103 1.1 mrg DECL_IGNORED_P (t) = 0;
104 1.1 mrg /* It should not be nameless. */
105 1.1 mrg DECL_NAMELESS (t) = 0;
106 1.1 mrg
107 1.1 mrg /* Make the variable writable. */
108 1.1 mrg TREE_READONLY (t) = 0;
109 1.1 mrg
110 1.1 mrg DECL_EXTERNAL (t) = 0;
111 1.1 mrg TREE_STATIC (t) = 0;
112 1.1 mrg TREE_USED (t) = 1;
113 1.1 mrg
114 1.1 mrg return t;
115 1.1 mrg }
116 1.1 mrg
117 1.1 mrg /* Creates a variable declaration with a given TYPE. */
118 1.1 mrg
119 1.1 mrg tree
120 1.1 mrg gfc_create_var_np (tree type, const char *prefix)
121 1.1 mrg {
122 1.1 mrg tree t;
123 1.1 mrg
124 1.1 mrg if (flag_debug_aux_vars)
125 1.1 mrg return create_var_debug_raw (type, prefix);
126 1.1 mrg
127 1.1 mrg t = create_tmp_var_raw (type, prefix);
128 1.1 mrg
129 1.1 mrg /* No warnings for anonymous variables. */
130 1.1 mrg if (prefix == NULL)
131 1.1 mrg suppress_warning (t);
132 1.1 mrg
133 1.1 mrg return t;
134 1.1 mrg }
135 1.1 mrg
136 1.1 mrg
137 1.1 mrg /* Like above, but also adds it to the current scope. */
138 1.1 mrg
139 1.1 mrg tree
140 1.1 mrg gfc_create_var (tree type, const char *prefix)
141 1.1 mrg {
142 1.1 mrg tree tmp;
143 1.1 mrg
144 1.1 mrg tmp = gfc_create_var_np (type, prefix);
145 1.1 mrg
146 1.1 mrg pushdecl (tmp);
147 1.1 mrg
148 1.1 mrg return tmp;
149 1.1 mrg }
150 1.1 mrg
151 1.1 mrg
152 1.1 mrg /* If the expression is not constant, evaluate it now. We assign the
153 1.1 mrg result of the expression to an artificially created variable VAR, and
154 1.1 mrg return a pointer to the VAR_DECL node for this variable. */
155 1.1 mrg
156 1.1 mrg tree
157 1.1 mrg gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
158 1.1 mrg {
159 1.1 mrg tree var;
160 1.1 mrg
161 1.1 mrg if (CONSTANT_CLASS_P (expr))
162 1.1 mrg return expr;
163 1.1 mrg
164 1.1 mrg var = gfc_create_var (TREE_TYPE (expr), NULL);
165 1.1 mrg gfc_add_modify_loc (loc, pblock, var, expr);
166 1.1 mrg
167 1.1 mrg return var;
168 1.1 mrg }
169 1.1 mrg
170 1.1 mrg
171 1.1 mrg tree
172 1.1 mrg gfc_evaluate_now (tree expr, stmtblock_t * pblock)
173 1.1 mrg {
174 1.1 mrg return gfc_evaluate_now_loc (input_location, expr, pblock);
175 1.1 mrg }
176 1.1 mrg
177 1.1 mrg /* Like gfc_evaluate_now, but add the created variable to the
178 1.1 mrg function scope. */
179 1.1 mrg
180 1.1 mrg tree
181 1.1 mrg gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
182 1.1 mrg {
183 1.1 mrg tree var;
184 1.1 mrg var = gfc_create_var_np (TREE_TYPE (expr), NULL);
185 1.1 mrg gfc_add_decl_to_function (var);
186 1.1 mrg gfc_add_modify (pblock, var, expr);
187 1.1 mrg
188 1.1 mrg return var;
189 1.1 mrg }
190 1.1 mrg
191 1.1 mrg /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
192 1.1 mrg A MODIFY_EXPR is an assignment:
193 1.1 mrg LHS <- RHS. */
194 1.1 mrg
195 1.1 mrg void
196 1.1 mrg gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
197 1.1 mrg {
198 1.1 mrg tree tmp;
199 1.1 mrg
200 1.1 mrg tree t1, t2;
201 1.1 mrg t1 = TREE_TYPE (rhs);
202 1.1 mrg t2 = TREE_TYPE (lhs);
203 1.1 mrg /* Make sure that the types of the rhs and the lhs are compatible
204 1.1 mrg for scalar assignments. We should probably have something
205 1.1 mrg similar for aggregates, but right now removing that check just
206 1.1 mrg breaks everything. */
207 1.1 mrg gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
208 1.1 mrg || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
209 1.1 mrg
210 1.1 mrg tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
211 1.1 mrg rhs);
212 1.1 mrg gfc_add_expr_to_block (pblock, tmp);
213 1.1 mrg }
214 1.1 mrg
215 1.1 mrg
216 1.1 mrg void
217 1.1 mrg gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
218 1.1 mrg {
219 1.1 mrg gfc_add_modify_loc (input_location, pblock, lhs, rhs);
220 1.1 mrg }
221 1.1 mrg
222 1.1 mrg
223 1.1 mrg /* Create a new scope/binding level and initialize a block. Care must be
224 1.1 mrg taken when translating expressions as any temporaries will be placed in
225 1.1 mrg the innermost scope. */
226 1.1 mrg
227 1.1 mrg void
228 1.1 mrg gfc_start_block (stmtblock_t * block)
229 1.1 mrg {
230 1.1 mrg /* Start a new binding level. */
231 1.1 mrg pushlevel ();
232 1.1 mrg block->has_scope = 1;
233 1.1 mrg
234 1.1 mrg /* The block is empty. */
235 1.1 mrg block->head = NULL_TREE;
236 1.1 mrg }
237 1.1 mrg
238 1.1 mrg
239 1.1 mrg /* Initialize a block without creating a new scope. */
240 1.1 mrg
241 1.1 mrg void
242 1.1 mrg gfc_init_block (stmtblock_t * block)
243 1.1 mrg {
244 1.1 mrg block->head = NULL_TREE;
245 1.1 mrg block->has_scope = 0;
246 1.1 mrg }
247 1.1 mrg
248 1.1 mrg
249 1.1 mrg /* Sometimes we create a scope but it turns out that we don't actually
250 1.1 mrg need it. This function merges the scope of BLOCK with its parent.
251 1.1 mrg Only variable decls will be merged, you still need to add the code. */
252 1.1 mrg
253 1.1 mrg void
254 1.1 mrg gfc_merge_block_scope (stmtblock_t * block)
255 1.1 mrg {
256 1.1 mrg tree decl;
257 1.1 mrg tree next;
258 1.1 mrg
259 1.1 mrg gcc_assert (block->has_scope);
260 1.1 mrg block->has_scope = 0;
261 1.1 mrg
262 1.1 mrg /* Remember the decls in this scope. */
263 1.1 mrg decl = getdecls ();
264 1.1 mrg poplevel (0, 0);
265 1.1 mrg
266 1.1 mrg /* Add them to the parent scope. */
267 1.1 mrg while (decl != NULL_TREE)
268 1.1 mrg {
269 1.1 mrg next = DECL_CHAIN (decl);
270 1.1 mrg DECL_CHAIN (decl) = NULL_TREE;
271 1.1 mrg
272 1.1 mrg pushdecl (decl);
273 1.1 mrg decl = next;
274 1.1 mrg }
275 1.1 mrg }
276 1.1 mrg
277 1.1 mrg
278 1.1 mrg /* Finish a scope containing a block of statements. */
279 1.1 mrg
280 1.1 mrg tree
281 1.1 mrg gfc_finish_block (stmtblock_t * stmtblock)
282 1.1 mrg {
283 1.1 mrg tree decl;
284 1.1 mrg tree expr;
285 1.1 mrg tree block;
286 1.1 mrg
287 1.1 mrg expr = stmtblock->head;
288 1.1 mrg if (!expr)
289 1.1 mrg expr = build_empty_stmt (input_location);
290 1.1 mrg
291 1.1 mrg stmtblock->head = NULL_TREE;
292 1.1 mrg
293 1.1 mrg if (stmtblock->has_scope)
294 1.1 mrg {
295 1.1 mrg decl = getdecls ();
296 1.1 mrg
297 1.1 mrg if (decl)
298 1.1 mrg {
299 1.1 mrg block = poplevel (1, 0);
300 1.1 mrg expr = build3_v (BIND_EXPR, decl, expr, block);
301 1.1 mrg }
302 1.1 mrg else
303 1.1 mrg poplevel (0, 0);
304 1.1 mrg }
305 1.1 mrg
306 1.1 mrg return expr;
307 1.1 mrg }
308 1.1 mrg
309 1.1 mrg
310 1.1 mrg /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
311 1.1 mrg natural type is used. */
312 1.1 mrg
313 1.1 mrg tree
314 1.1 mrg gfc_build_addr_expr (tree type, tree t)
315 1.1 mrg {
316 1.1 mrg tree base_type = TREE_TYPE (t);
317 1.1 mrg tree natural_type;
318 1.1 mrg
319 1.1 mrg if (type && POINTER_TYPE_P (type)
320 1.1 mrg && TREE_CODE (base_type) == ARRAY_TYPE
321 1.1 mrg && TYPE_MAIN_VARIANT (TREE_TYPE (type))
322 1.1 mrg == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
323 1.1 mrg {
324 1.1 mrg tree min_val = size_zero_node;
325 1.1 mrg tree type_domain = TYPE_DOMAIN (base_type);
326 1.1 mrg if (type_domain && TYPE_MIN_VALUE (type_domain))
327 1.1 mrg min_val = TYPE_MIN_VALUE (type_domain);
328 1.1 mrg t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
329 1.1 mrg t, min_val, NULL_TREE, NULL_TREE));
330 1.1 mrg natural_type = type;
331 1.1 mrg }
332 1.1 mrg else
333 1.1 mrg natural_type = build_pointer_type (base_type);
334 1.1 mrg
335 1.1 mrg if (TREE_CODE (t) == INDIRECT_REF)
336 1.1 mrg {
337 1.1 mrg if (!type)
338 1.1 mrg type = natural_type;
339 1.1 mrg t = TREE_OPERAND (t, 0);
340 1.1 mrg natural_type = TREE_TYPE (t);
341 1.1 mrg }
342 1.1 mrg else
343 1.1 mrg {
344 1.1 mrg tree base = get_base_address (t);
345 1.1 mrg if (base && DECL_P (base))
346 1.1 mrg TREE_ADDRESSABLE (base) = 1;
347 1.1 mrg t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
348 1.1 mrg }
349 1.1 mrg
350 1.1 mrg if (type && natural_type != type)
351 1.1 mrg t = convert (type, t);
352 1.1 mrg
353 1.1 mrg return t;
354 1.1 mrg }
355 1.1 mrg
356 1.1 mrg
357 1.1 mrg static tree
358 1.1 mrg get_array_span (tree type, tree decl)
359 1.1 mrg {
360 1.1 mrg tree span;
361 1.1 mrg
362 1.1 mrg /* Component references are guaranteed to have a reliable value for
363 1.1 mrg 'span'. Likewise indirect references since they emerge from the
364 1.1 mrg conversion of a CFI descriptor or the hidden dummy descriptor. */
365 1.1 mrg if (TREE_CODE (decl) == COMPONENT_REF
366 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
367 1.1 mrg return gfc_conv_descriptor_span_get (decl);
368 1.1 mrg else if (TREE_CODE (decl) == INDIRECT_REF
369 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
370 1.1 mrg return gfc_conv_descriptor_span_get (decl);
371 1.1 mrg
372 1.1 mrg /* Return the span for deferred character length array references. */
373 1.1 mrg if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
374 1.1 mrg {
375 1.1 mrg if (TREE_CODE (decl) == PARM_DECL)
376 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
377 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
378 1.1 mrg span = gfc_conv_descriptor_span_get (decl);
379 1.1 mrg else
380 1.1 mrg span = gfc_get_character_len_in_bytes (type);
381 1.1 mrg span = (span && !integer_zerop (span))
382 1.1 mrg ? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE);
383 1.1 mrg }
384 1.1 mrg /* Likewise for class array or pointer array references. */
385 1.1 mrg else if (TREE_CODE (decl) == FIELD_DECL
386 1.1 mrg || VAR_OR_FUNCTION_DECL_P (decl)
387 1.1 mrg || TREE_CODE (decl) == PARM_DECL)
388 1.1 mrg {
389 1.1 mrg if (GFC_DECL_CLASS (decl))
390 1.1 mrg {
391 1.1 mrg /* When a temporary is in place for the class array, then the
392 1.1 mrg original class' declaration is stored in the saved
393 1.1 mrg descriptor. */
394 1.1 mrg if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
395 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
396 1.1 mrg else
397 1.1 mrg {
398 1.1 mrg /* Allow for dummy arguments and other good things. */
399 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl)))
400 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
401 1.1 mrg
402 1.1 mrg /* Check if '_data' is an array descriptor. If it is not,
403 1.1 mrg the array must be one of the components of the class
404 1.1 mrg object, so return a null span. */
405 1.1 mrg if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
406 1.1 mrg gfc_class_data_get (decl))))
407 1.1 mrg return NULL_TREE;
408 1.1 mrg }
409 1.1 mrg span = gfc_class_vtab_size_get (decl);
410 1.1 mrg /* For unlimited polymorphic entities then _len component needs
411 1.1 mrg to be multiplied with the size. */
412 1.1 mrg span = gfc_resize_class_size_with_len (NULL, decl, span);
413 1.1 mrg }
414 1.1 mrg else if (GFC_DECL_PTR_ARRAY_P (decl))
415 1.1 mrg {
416 1.1 mrg if (TREE_CODE (decl) == PARM_DECL)
417 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl);
418 1.1 mrg span = gfc_conv_descriptor_span_get (decl);
419 1.1 mrg }
420 1.1 mrg else
421 1.1 mrg span = NULL_TREE;
422 1.1 mrg }
423 1.1 mrg else
424 1.1 mrg span = NULL_TREE;
425 1.1 mrg
426 1.1 mrg return span;
427 1.1 mrg }
428 1.1 mrg
429 1.1 mrg
430 1.1 mrg tree
431 1.1 mrg gfc_build_spanned_array_ref (tree base, tree offset, tree span)
432 1.1 mrg {
433 1.1 mrg tree type;
434 1.1 mrg tree tmp;
435 1.1 mrg type = TREE_TYPE (TREE_TYPE (base));
436 1.1 mrg offset = fold_build2_loc (input_location, MULT_EXPR,
437 1.1 mrg gfc_array_index_type,
438 1.1 mrg offset, span);
439 1.1 mrg tmp = gfc_build_addr_expr (pvoid_type_node, base);
440 1.1 mrg tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
441 1.1 mrg tmp = fold_convert (build_pointer_type (type), tmp);
442 1.1 mrg if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
443 1.1 mrg || !TYPE_STRING_FLAG (type))
444 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
445 1.1 mrg return tmp;
446 1.1 mrg }
447 1.1 mrg
448 1.1 mrg
449 1.1 mrg /* Build an ARRAY_REF with its natural type.
450 1.1 mrg NON_NEGATIVE_OFFSET indicates if its true that OFFSET cant be negative,
451 1.1 mrg and thus that an ARRAY_REF can safely be generated. If its false, we
452 1.1 mrg have to play it safe and use pointer arithmetic. */
453 1.1 mrg
454 1.1 mrg tree
455 1.1 mrg gfc_build_array_ref (tree base, tree offset, tree decl,
456 1.1 mrg bool non_negative_offset, tree vptr)
457 1.1 mrg {
458 1.1 mrg tree type = TREE_TYPE (base);
459 1.1 mrg tree span = NULL_TREE;
460 1.1 mrg
461 1.1 mrg if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
462 1.1 mrg {
463 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
464 1.1 mrg
465 1.1 mrg return fold_convert (TYPE_MAIN_VARIANT (type), base);
466 1.1 mrg }
467 1.1 mrg
468 1.1 mrg /* Scalar coarray, there is nothing to do. */
469 1.1 mrg if (TREE_CODE (type) != ARRAY_TYPE)
470 1.1 mrg {
471 1.1 mrg gcc_assert (decl == NULL_TREE);
472 1.1 mrg gcc_assert (integer_zerop (offset));
473 1.1 mrg return base;
474 1.1 mrg }
475 1.1 mrg
476 1.1 mrg type = TREE_TYPE (type);
477 1.1 mrg
478 1.1 mrg if (DECL_P (base))
479 1.1 mrg TREE_ADDRESSABLE (base) = 1;
480 1.1 mrg
481 1.1 mrg /* Strip NON_LVALUE_EXPR nodes. */
482 1.1 mrg STRIP_TYPE_NOPS (offset);
483 1.1 mrg
484 1.1 mrg /* If decl or vptr are non-null, pointer arithmetic for the array reference
485 1.1 mrg is likely. Generate the 'span' for the array reference. */
486 1.1 mrg if (vptr)
487 1.1 mrg {
488 1.1 mrg span = gfc_vptr_size_get (vptr);
489 1.1 mrg
490 1.1 mrg /* Check if this is an unlimited polymorphic object carrying a character
491 1.1 mrg payload. In this case, the 'len' field is non-zero. */
492 1.1 mrg if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
493 1.1 mrg span = gfc_resize_class_size_with_len (NULL, decl, span);
494 1.1 mrg }
495 1.1 mrg else if (decl)
496 1.1 mrg span = get_array_span (type, decl);
497 1.1 mrg
498 1.1 mrg /* If a non-null span has been generated reference the element with
499 1.1 mrg pointer arithmetic. */
500 1.1 mrg if (span != NULL_TREE)
501 1.1 mrg return gfc_build_spanned_array_ref (base, offset, span);
502 1.1 mrg /* Else use a straightforward array reference if possible. */
503 1.1 mrg else if (non_negative_offset)
504 1.1 mrg return build4_loc (input_location, ARRAY_REF, type, base, offset,
505 1.1 mrg NULL_TREE, NULL_TREE);
506 1.1 mrg /* Otherwise use pointer arithmetic. */
507 1.1 mrg else
508 1.1 mrg {
509 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
510 1.1 mrg tree min = NULL_TREE;
511 1.1 mrg if (TYPE_DOMAIN (TREE_TYPE (base))
512 1.1 mrg && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
513 1.1 mrg min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
514 1.1 mrg
515 1.1 mrg tree zero_based_index
516 1.1 mrg = min ? fold_build2_loc (input_location, MINUS_EXPR,
517 1.1 mrg gfc_array_index_type,
518 1.1 mrg fold_convert (gfc_array_index_type, offset),
519 1.1 mrg fold_convert (gfc_array_index_type, min))
520 1.1 mrg : fold_convert (gfc_array_index_type, offset);
521 1.1 mrg
522 1.1 mrg tree elt_size = fold_convert (gfc_array_index_type,
523 1.1 mrg TYPE_SIZE_UNIT (type));
524 1.1 mrg
525 1.1 mrg tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
526 1.1 mrg gfc_array_index_type,
527 1.1 mrg zero_based_index, elt_size);
528 1.1 mrg
529 1.1 mrg tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
530 1.1 mrg
531 1.1 mrg tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
532 1.1 mrg offset_bytes);
533 1.1 mrg return build1_loc (input_location, INDIRECT_REF, type,
534 1.1 mrg fold_convert (build_pointer_type (type), ptr));
535 1.1 mrg }
536 1.1 mrg }
537 1.1 mrg
538 1.1 mrg
539 1.1 mrg /* Generate a call to print a runtime error possibly including multiple
540 1.1 mrg arguments and a locus. */
541 1.1 mrg
542 1.1 mrg static tree
543 1.1 mrg trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
544 1.1 mrg va_list ap)
545 1.1 mrg {
546 1.1 mrg stmtblock_t block;
547 1.1 mrg tree tmp;
548 1.1 mrg tree arg, arg2;
549 1.1 mrg tree *argarray;
550 1.1 mrg tree fntype;
551 1.1 mrg char *message;
552 1.1 mrg const char *p;
553 1.1 mrg int line, nargs, i;
554 1.1 mrg location_t loc;
555 1.1 mrg
556 1.1 mrg /* Compute the number of extra arguments from the format string. */
557 1.1 mrg for (p = msgid, nargs = 0; *p; p++)
558 1.1 mrg if (*p == '%')
559 1.1 mrg {
560 1.1 mrg p++;
561 1.1 mrg if (*p != '%')
562 1.1 mrg nargs++;
563 1.1 mrg }
564 1.1 mrg
565 1.1 mrg /* The code to generate the error. */
566 1.1 mrg gfc_start_block (&block);
567 1.1 mrg
568 1.1 mrg if (where)
569 1.1 mrg {
570 1.1 mrg line = LOCATION_LINE (where->lb->location);
571 1.1 mrg message = xasprintf ("At line %d of file %s", line,
572 1.1 mrg where->lb->file->filename);
573 1.1 mrg }
574 1.1 mrg else
575 1.1 mrg message = xasprintf ("In file '%s', around line %d",
576 1.1 mrg gfc_source_file, LOCATION_LINE (input_location) + 1);
577 1.1 mrg
578 1.1 mrg arg = gfc_build_addr_expr (pchar_type_node,
579 1.1 mrg gfc_build_localized_cstring_const (message));
580 1.1 mrg free (message);
581 1.1 mrg
582 1.1 mrg message = xasprintf ("%s", _(msgid));
583 1.1 mrg arg2 = gfc_build_addr_expr (pchar_type_node,
584 1.1 mrg gfc_build_localized_cstring_const (message));
585 1.1 mrg free (message);
586 1.1 mrg
587 1.1 mrg /* Build the argument array. */
588 1.1 mrg argarray = XALLOCAVEC (tree, nargs + 2);
589 1.1 mrg argarray[0] = arg;
590 1.1 mrg argarray[1] = arg2;
591 1.1 mrg for (i = 0; i < nargs; i++)
592 1.1 mrg argarray[2 + i] = va_arg (ap, tree);
593 1.1 mrg
594 1.1 mrg /* Build the function call to runtime_(warning,error)_at; because of the
595 1.1 mrg variable number of arguments, we can't use build_call_expr_loc dinput_location,
596 1.1 mrg irectly. */
597 1.1 mrg fntype = TREE_TYPE (errorfunc);
598 1.1 mrg
599 1.1 mrg loc = where ? gfc_get_location (where) : input_location;
600 1.1 mrg tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
601 1.1 mrg fold_build1_loc (loc, ADDR_EXPR,
602 1.1 mrg build_pointer_type (fntype),
603 1.1 mrg errorfunc),
604 1.1 mrg nargs + 2, argarray);
605 1.1 mrg gfc_add_expr_to_block (&block, tmp);
606 1.1 mrg
607 1.1 mrg return gfc_finish_block (&block);
608 1.1 mrg }
609 1.1 mrg
610 1.1 mrg
611 1.1 mrg tree
612 1.1 mrg gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
613 1.1 mrg {
614 1.1 mrg va_list ap;
615 1.1 mrg tree result;
616 1.1 mrg
617 1.1 mrg va_start (ap, msgid);
618 1.1 mrg result = trans_runtime_error_vararg (error
619 1.1 mrg ? gfor_fndecl_runtime_error_at
620 1.1 mrg : gfor_fndecl_runtime_warning_at,
621 1.1 mrg where, msgid, ap);
622 1.1 mrg va_end (ap);
623 1.1 mrg return result;
624 1.1 mrg }
625 1.1 mrg
626 1.1 mrg
627 1.1 mrg /* Generate a runtime error if COND is true. */
628 1.1 mrg
629 1.1 mrg void
630 1.1 mrg gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
631 1.1 mrg locus * where, const char * msgid, ...)
632 1.1 mrg {
633 1.1 mrg va_list ap;
634 1.1 mrg stmtblock_t block;
635 1.1 mrg tree body;
636 1.1 mrg tree tmp;
637 1.1 mrg tree tmpvar = NULL;
638 1.1 mrg
639 1.1 mrg if (integer_zerop (cond))
640 1.1 mrg return;
641 1.1 mrg
642 1.1 mrg if (once)
643 1.1 mrg {
644 1.1 mrg tmpvar = gfc_create_var (boolean_type_node, "print_warning");
645 1.1 mrg TREE_STATIC (tmpvar) = 1;
646 1.1 mrg DECL_INITIAL (tmpvar) = boolean_true_node;
647 1.1 mrg gfc_add_expr_to_block (pblock, tmpvar);
648 1.1 mrg }
649 1.1 mrg
650 1.1 mrg gfc_start_block (&block);
651 1.1 mrg
652 1.1 mrg /* For error, runtime_error_at already implies PRED_NORETURN. */
653 1.1 mrg if (!error && once)
654 1.1 mrg gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
655 1.1 mrg NOT_TAKEN));
656 1.1 mrg
657 1.1 mrg /* The code to generate the error. */
658 1.1 mrg va_start (ap, msgid);
659 1.1 mrg gfc_add_expr_to_block (&block,
660 1.1 mrg trans_runtime_error_vararg
661 1.1 mrg (error ? gfor_fndecl_runtime_error_at
662 1.1 mrg : gfor_fndecl_runtime_warning_at,
663 1.1 mrg where, msgid, ap));
664 1.1 mrg va_end (ap);
665 1.1 mrg
666 1.1 mrg if (once)
667 1.1 mrg gfc_add_modify (&block, tmpvar, boolean_false_node);
668 1.1 mrg
669 1.1 mrg body = gfc_finish_block (&block);
670 1.1 mrg
671 1.1 mrg if (integer_onep (cond))
672 1.1 mrg {
673 1.1 mrg gfc_add_expr_to_block (pblock, body);
674 1.1 mrg }
675 1.1 mrg else
676 1.1 mrg {
677 1.1 mrg if (once)
678 1.1 mrg cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
679 1.1 mrg boolean_type_node, tmpvar,
680 1.1 mrg fold_convert (boolean_type_node, cond));
681 1.1 mrg
682 1.1 mrg tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
683 1.1 mrg cond, body,
684 1.1 mrg build_empty_stmt (gfc_get_location (where)));
685 1.1 mrg gfc_add_expr_to_block (pblock, tmp);
686 1.1 mrg }
687 1.1 mrg }
688 1.1 mrg
689 1.1 mrg
690 1.1 mrg static tree
691 1.1 mrg trans_os_error_at (locus* where, const char* msgid, ...)
692 1.1 mrg {
693 1.1 mrg va_list ap;
694 1.1 mrg tree result;
695 1.1 mrg
696 1.1 mrg va_start (ap, msgid);
697 1.1 mrg result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
698 1.1 mrg where, msgid, ap);
699 1.1 mrg va_end (ap);
700 1.1 mrg return result;
701 1.1 mrg }
702 1.1 mrg
703 1.1 mrg
704 1.1 mrg
705 1.1 mrg /* Call malloc to allocate size bytes of memory, with special conditions:
706 1.1 mrg + if size == 0, return a malloced area of size 1,
707 1.1 mrg + if malloc returns NULL, issue a runtime error. */
708 1.1 mrg tree
709 1.1 mrg gfc_call_malloc (stmtblock_t * block, tree type, tree size)
710 1.1 mrg {
711 1.1 mrg tree tmp, malloc_result, null_result, res, malloc_tree;
712 1.1 mrg stmtblock_t block2;
713 1.1 mrg
714 1.1 mrg /* Create a variable to hold the result. */
715 1.1 mrg res = gfc_create_var (prvoid_type_node, NULL);
716 1.1 mrg
717 1.1 mrg /* Call malloc. */
718 1.1 mrg gfc_start_block (&block2);
719 1.1 mrg
720 1.1 mrg if (size == NULL_TREE)
721 1.1 mrg size = build_int_cst (size_type_node, 1);
722 1.1 mrg
723 1.1 mrg size = fold_convert (size_type_node, size);
724 1.1 mrg size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
725 1.1 mrg build_int_cst (size_type_node, 1));
726 1.1 mrg
727 1.1 mrg malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
728 1.1 mrg gfc_add_modify (&block2, res,
729 1.1 mrg fold_convert (prvoid_type_node,
730 1.1 mrg build_call_expr_loc (input_location,
731 1.1 mrg malloc_tree, 1, size)));
732 1.1 mrg
733 1.1 mrg /* Optionally check whether malloc was successful. */
734 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
735 1.1 mrg {
736 1.1 mrg null_result = fold_build2_loc (input_location, EQ_EXPR,
737 1.1 mrg logical_type_node, res,
738 1.1 mrg build_int_cst (pvoid_type_node, 0));
739 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
740 1.1 mrg null_result,
741 1.1 mrg trans_os_error_at (NULL,
742 1.1 mrg "Error allocating %lu bytes",
743 1.1 mrg fold_convert
744 1.1 mrg (long_unsigned_type_node,
745 1.1 mrg size)),
746 1.1 mrg build_empty_stmt (input_location));
747 1.1 mrg gfc_add_expr_to_block (&block2, tmp);
748 1.1 mrg }
749 1.1 mrg
750 1.1 mrg malloc_result = gfc_finish_block (&block2);
751 1.1 mrg gfc_add_expr_to_block (block, malloc_result);
752 1.1 mrg
753 1.1 mrg if (type != NULL)
754 1.1 mrg res = fold_convert (type, res);
755 1.1 mrg return res;
756 1.1 mrg }
757 1.1 mrg
758 1.1 mrg
759 1.1 mrg /* Allocate memory, using an optional status argument.
760 1.1 mrg
761 1.1 mrg This function follows the following pseudo-code:
762 1.1 mrg
763 1.1 mrg void *
764 1.1 mrg allocate (size_t size, integer_type stat)
765 1.1 mrg {
766 1.1 mrg void *newmem;
767 1.1 mrg
768 1.1 mrg if (stat requested)
769 1.1 mrg stat = 0;
770 1.1 mrg
771 1.1 mrg newmem = malloc (MAX (size, 1));
772 1.1 mrg if (newmem == NULL)
773 1.1 mrg {
774 1.1 mrg if (stat)
775 1.1 mrg *stat = LIBERROR_ALLOCATION;
776 1.1 mrg else
777 1.1 mrg runtime_error ("Allocation would exceed memory limit");
778 1.1 mrg }
779 1.1 mrg return newmem;
780 1.1 mrg } */
781 1.1 mrg void
782 1.1 mrg gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
783 1.1 mrg tree size, tree status)
784 1.1 mrg {
785 1.1 mrg tree tmp, error_cond;
786 1.1 mrg stmtblock_t on_error;
787 1.1 mrg tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
788 1.1 mrg
789 1.1 mrg /* If successful and stat= is given, set status to 0. */
790 1.1 mrg if (status != NULL_TREE)
791 1.1 mrg gfc_add_expr_to_block (block,
792 1.1 mrg fold_build2_loc (input_location, MODIFY_EXPR, status_type,
793 1.1 mrg status, build_int_cst (status_type, 0)));
794 1.1 mrg
795 1.1 mrg /* The allocation itself. */
796 1.1 mrg size = fold_convert (size_type_node, size);
797 1.1 mrg gfc_add_modify (block, pointer,
798 1.1 mrg fold_convert (TREE_TYPE (pointer),
799 1.1 mrg build_call_expr_loc (input_location,
800 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC), 1,
801 1.1 mrg fold_build2_loc (input_location,
802 1.1 mrg MAX_EXPR, size_type_node, size,
803 1.1 mrg build_int_cst (size_type_node, 1)))));
804 1.1 mrg
805 1.1 mrg /* What to do in case of error. */
806 1.1 mrg gfc_start_block (&on_error);
807 1.1 mrg if (status != NULL_TREE)
808 1.1 mrg {
809 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
810 1.1 mrg build_int_cst (status_type, LIBERROR_ALLOCATION));
811 1.1 mrg gfc_add_expr_to_block (&on_error, tmp);
812 1.1 mrg }
813 1.1 mrg else
814 1.1 mrg {
815 1.1 mrg /* Here, os_error_at already implies PRED_NORETURN. */
816 1.1 mrg tree lusize = fold_convert (long_unsigned_type_node, size);
817 1.1 mrg tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
818 1.1 mrg gfc_add_expr_to_block (&on_error, tmp);
819 1.1 mrg }
820 1.1 mrg
821 1.1 mrg error_cond = fold_build2_loc (input_location, EQ_EXPR,
822 1.1 mrg logical_type_node, pointer,
823 1.1 mrg build_int_cst (prvoid_type_node, 0));
824 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
825 1.1 mrg gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
826 1.1 mrg gfc_finish_block (&on_error),
827 1.1 mrg build_empty_stmt (input_location));
828 1.1 mrg
829 1.1 mrg gfc_add_expr_to_block (block, tmp);
830 1.1 mrg }
831 1.1 mrg
832 1.1 mrg
833 1.1 mrg /* Allocate memory, using an optional status argument.
834 1.1 mrg
835 1.1 mrg This function follows the following pseudo-code:
836 1.1 mrg
837 1.1 mrg void *
838 1.1 mrg allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
839 1.1 mrg {
840 1.1 mrg void *newmem;
841 1.1 mrg
842 1.1 mrg newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
843 1.1 mrg return newmem;
844 1.1 mrg } */
845 1.1 mrg void
846 1.1 mrg gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
847 1.1 mrg tree token, tree status, tree errmsg, tree errlen,
848 1.1 mrg gfc_coarray_regtype alloc_type)
849 1.1 mrg {
850 1.1 mrg tree tmp, pstat;
851 1.1 mrg
852 1.1 mrg gcc_assert (token != NULL_TREE);
853 1.1 mrg
854 1.1 mrg /* The allocation itself. */
855 1.1 mrg if (status == NULL_TREE)
856 1.1 mrg pstat = null_pointer_node;
857 1.1 mrg else
858 1.1 mrg pstat = gfc_build_addr_expr (NULL_TREE, status);
859 1.1 mrg
860 1.1 mrg if (errmsg == NULL_TREE)
861 1.1 mrg {
862 1.1 mrg gcc_assert(errlen == NULL_TREE);
863 1.1 mrg errmsg = null_pointer_node;
864 1.1 mrg errlen = build_int_cst (integer_type_node, 0);
865 1.1 mrg }
866 1.1 mrg
867 1.1 mrg size = fold_convert (size_type_node, size);
868 1.1 mrg tmp = build_call_expr_loc (input_location,
869 1.1 mrg gfor_fndecl_caf_register, 7,
870 1.1 mrg fold_build2_loc (input_location,
871 1.1 mrg MAX_EXPR, size_type_node, size, size_one_node),
872 1.1 mrg build_int_cst (integer_type_node, alloc_type),
873 1.1 mrg token, gfc_build_addr_expr (pvoid_type_node, pointer),
874 1.1 mrg pstat, errmsg, errlen);
875 1.1 mrg
876 1.1 mrg gfc_add_expr_to_block (block, tmp);
877 1.1 mrg
878 1.1 mrg /* It guarantees memory consistency within the same segment */
879 1.1 mrg tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
880 1.1 mrg tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
881 1.1 mrg gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
882 1.1 mrg tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
883 1.1 mrg ASM_VOLATILE_P (tmp) = 1;
884 1.1 mrg gfc_add_expr_to_block (block, tmp);
885 1.1 mrg }
886 1.1 mrg
887 1.1 mrg
888 1.1 mrg /* Generate code for an ALLOCATE statement when the argument is an
889 1.1 mrg allocatable variable. If the variable is currently allocated, it is an
890 1.1 mrg error to allocate it again.
891 1.1 mrg
892 1.1 mrg This function follows the following pseudo-code:
893 1.1 mrg
894 1.1 mrg void *
895 1.1 mrg allocate_allocatable (void *mem, size_t size, integer_type stat)
896 1.1 mrg {
897 1.1 mrg if (mem == NULL)
898 1.1 mrg return allocate (size, stat);
899 1.1 mrg else
900 1.1 mrg {
901 1.1 mrg if (stat)
902 1.1 mrg stat = LIBERROR_ALLOCATION;
903 1.1 mrg else
904 1.1 mrg runtime_error ("Attempting to allocate already allocated variable");
905 1.1 mrg }
906 1.1 mrg }
907 1.1 mrg
908 1.1 mrg expr must be set to the original expression being allocated for its locus
909 1.1 mrg and variable name in case a runtime error has to be printed. */
910 1.1 mrg void
911 1.1 mrg gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
912 1.1 mrg tree token, tree status, tree errmsg, tree errlen,
913 1.1 mrg tree label_finish, gfc_expr* expr, int corank)
914 1.1 mrg {
915 1.1 mrg stmtblock_t alloc_block;
916 1.1 mrg tree tmp, null_mem, alloc, error;
917 1.1 mrg tree type = TREE_TYPE (mem);
918 1.1 mrg symbol_attribute caf_attr;
919 1.1 mrg bool need_assign = false, refs_comp = false;
920 1.1 mrg gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
921 1.1 mrg
922 1.1 mrg size = fold_convert (size_type_node, size);
923 1.1 mrg null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
924 1.1 mrg logical_type_node, mem,
925 1.1 mrg build_int_cst (type, 0)),
926 1.1 mrg PRED_FORTRAN_REALLOC);
927 1.1 mrg
928 1.1 mrg /* If mem is NULL, we call gfc_allocate_using_malloc or
929 1.1 mrg gfc_allocate_using_lib. */
930 1.1 mrg gfc_start_block (&alloc_block);
931 1.1 mrg
932 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
933 1.1 mrg caf_attr = gfc_caf_attr (expr, true, &refs_comp);
934 1.1 mrg
935 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB
936 1.1 mrg && (corank > 0 || caf_attr.codimension))
937 1.1 mrg {
938 1.1 mrg tree cond, sub_caf_tree;
939 1.1 mrg gfc_se se;
940 1.1 mrg bool compute_special_caf_types_size = false;
941 1.1 mrg
942 1.1 mrg if (expr->ts.type == BT_DERIVED
943 1.1 mrg && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
944 1.1 mrg && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
945 1.1 mrg {
946 1.1 mrg compute_special_caf_types_size = true;
947 1.1 mrg caf_alloc_type = GFC_CAF_LOCK_ALLOC;
948 1.1 mrg }
949 1.1 mrg else if (expr->ts.type == BT_DERIVED
950 1.1 mrg && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
951 1.1 mrg && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
952 1.1 mrg {
953 1.1 mrg compute_special_caf_types_size = true;
954 1.1 mrg caf_alloc_type = GFC_CAF_EVENT_ALLOC;
955 1.1 mrg }
956 1.1 mrg else if (!caf_attr.coarray_comp && refs_comp)
957 1.1 mrg /* Only allocatable components in a derived type coarray can be
958 1.1 mrg allocate only. */
959 1.1 mrg caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
960 1.1 mrg
961 1.1 mrg gfc_init_se (&se, NULL);
962 1.1 mrg sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
963 1.1 mrg if (sub_caf_tree == NULL_TREE)
964 1.1 mrg sub_caf_tree = token;
965 1.1 mrg
966 1.1 mrg /* When mem is an array ref, then strip the .data-ref. */
967 1.1 mrg if (TREE_CODE (mem) == COMPONENT_REF
968 1.1 mrg && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
969 1.1 mrg tmp = TREE_OPERAND (mem, 0);
970 1.1 mrg else
971 1.1 mrg tmp = mem;
972 1.1 mrg
973 1.1 mrg if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
974 1.1 mrg && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
975 1.1 mrg && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
976 1.1 mrg {
977 1.1 mrg symbol_attribute attr;
978 1.1 mrg
979 1.1 mrg gfc_clear_attr (&attr);
980 1.1 mrg tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
981 1.1 mrg need_assign = true;
982 1.1 mrg }
983 1.1 mrg gfc_add_block_to_block (&alloc_block, &se.pre);
984 1.1 mrg
985 1.1 mrg /* In the front end, we represent the lock variable as pointer. However,
986 1.1 mrg the FE only passes the pointer around and leaves the actual
987 1.1 mrg representation to the library. Hence, we have to convert back to the
988 1.1 mrg number of elements. */
989 1.1 mrg if (compute_special_caf_types_size)
990 1.1 mrg size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
991 1.1 mrg size, TYPE_SIZE_UNIT (ptr_type_node));
992 1.1 mrg
993 1.1 mrg gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
994 1.1 mrg status, errmsg, errlen, caf_alloc_type);
995 1.1 mrg if (need_assign)
996 1.1 mrg gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
997 1.1 mrg gfc_conv_descriptor_data_get (tmp)));
998 1.1 mrg if (status != NULL_TREE)
999 1.1 mrg {
1000 1.1 mrg TREE_USED (label_finish) = 1;
1001 1.1 mrg tmp = build1_v (GOTO_EXPR, label_finish);
1002 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1003 1.1 mrg status, build_zero_cst (TREE_TYPE (status)));
1004 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1005 1.1 mrg gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
1006 1.1 mrg tmp, build_empty_stmt (input_location));
1007 1.1 mrg gfc_add_expr_to_block (&alloc_block, tmp);
1008 1.1 mrg }
1009 1.1 mrg }
1010 1.1 mrg else
1011 1.1 mrg gfc_allocate_using_malloc (&alloc_block, mem, size, status);
1012 1.1 mrg
1013 1.1 mrg alloc = gfc_finish_block (&alloc_block);
1014 1.1 mrg
1015 1.1 mrg /* If mem is not NULL, we issue a runtime error or set the
1016 1.1 mrg status variable. */
1017 1.1 mrg if (expr)
1018 1.1 mrg {
1019 1.1 mrg tree varname;
1020 1.1 mrg
1021 1.1 mrg gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
1022 1.1 mrg varname = gfc_build_cstring_const (expr->symtree->name);
1023 1.1 mrg varname = gfc_build_addr_expr (pchar_type_node, varname);
1024 1.1 mrg
1025 1.1 mrg error = gfc_trans_runtime_error (true, &expr->where,
1026 1.1 mrg "Attempting to allocate already"
1027 1.1 mrg " allocated variable '%s'",
1028 1.1 mrg varname);
1029 1.1 mrg }
1030 1.1 mrg else
1031 1.1 mrg error = gfc_trans_runtime_error (true, NULL,
1032 1.1 mrg "Attempting to allocate already allocated"
1033 1.1 mrg " variable");
1034 1.1 mrg
1035 1.1 mrg if (status != NULL_TREE)
1036 1.1 mrg {
1037 1.1 mrg tree status_type = TREE_TYPE (status);
1038 1.1 mrg
1039 1.1 mrg error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1040 1.1 mrg status, build_int_cst (status_type, LIBERROR_ALLOCATION));
1041 1.1 mrg }
1042 1.1 mrg
1043 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
1044 1.1 mrg error, alloc);
1045 1.1 mrg gfc_add_expr_to_block (block, tmp);
1046 1.1 mrg }
1047 1.1 mrg
1048 1.1 mrg
1049 1.1 mrg /* Free a given variable. */
1050 1.1 mrg
1051 1.1 mrg tree
1052 1.1 mrg gfc_call_free (tree var)
1053 1.1 mrg {
1054 1.1 mrg return build_call_expr_loc (input_location,
1055 1.1 mrg builtin_decl_explicit (BUILT_IN_FREE),
1056 1.1 mrg 1, fold_convert (pvoid_type_node, var));
1057 1.1 mrg }
1058 1.1 mrg
1059 1.1 mrg
1060 1.1 mrg /* Build a call to a FINAL procedure, which finalizes "var". */
1061 1.1 mrg
1062 1.1 mrg static tree
1063 1.1 mrg gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
1064 1.1 mrg bool fini_coarray, gfc_expr *class_size)
1065 1.1 mrg {
1066 1.1 mrg stmtblock_t block;
1067 1.1 mrg gfc_se se;
1068 1.1 mrg tree final_fndecl, array, size, tmp;
1069 1.1 mrg symbol_attribute attr;
1070 1.1 mrg
1071 1.1 mrg gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1072 1.1 mrg gcc_assert (var);
1073 1.1 mrg
1074 1.1 mrg gfc_start_block (&block);
1075 1.1 mrg gfc_init_se (&se, NULL);
1076 1.1 mrg gfc_conv_expr (&se, final_wrapper);
1077 1.1 mrg final_fndecl = se.expr;
1078 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1079 1.1 mrg final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1080 1.1 mrg
1081 1.1 mrg if (ts.type == BT_DERIVED)
1082 1.1 mrg {
1083 1.1 mrg tree elem_size;
1084 1.1 mrg
1085 1.1 mrg gcc_assert (!class_size);
1086 1.1 mrg elem_size = gfc_typenode_for_spec (&ts);
1087 1.1 mrg elem_size = TYPE_SIZE_UNIT (elem_size);
1088 1.1 mrg size = fold_convert (gfc_array_index_type, elem_size);
1089 1.1 mrg
1090 1.1 mrg gfc_init_se (&se, NULL);
1091 1.1 mrg se.want_pointer = 1;
1092 1.1 mrg if (var->rank)
1093 1.1 mrg {
1094 1.1 mrg se.descriptor_only = 1;
1095 1.1 mrg gfc_conv_expr_descriptor (&se, var);
1096 1.1 mrg array = se.expr;
1097 1.1 mrg }
1098 1.1 mrg else
1099 1.1 mrg {
1100 1.1 mrg gfc_conv_expr (&se, var);
1101 1.1 mrg gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
1102 1.1 mrg array = se.expr;
1103 1.1 mrg
1104 1.1 mrg /* No copy back needed, hence set attr's allocatable/pointer
1105 1.1 mrg to zero. */
1106 1.1 mrg gfc_clear_attr (&attr);
1107 1.1 mrg gfc_init_se (&se, NULL);
1108 1.1 mrg array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1109 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
1110 1.1 mrg }
1111 1.1 mrg }
1112 1.1 mrg else
1113 1.1 mrg {
1114 1.1 mrg gfc_expr *array_expr;
1115 1.1 mrg gcc_assert (class_size);
1116 1.1 mrg gfc_init_se (&se, NULL);
1117 1.1 mrg gfc_conv_expr (&se, class_size);
1118 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
1119 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
1120 1.1 mrg size = se.expr;
1121 1.1 mrg
1122 1.1 mrg array_expr = gfc_copy_expr (var);
1123 1.1 mrg gfc_init_se (&se, NULL);
1124 1.1 mrg se.want_pointer = 1;
1125 1.1 mrg if (array_expr->rank)
1126 1.1 mrg {
1127 1.1 mrg gfc_add_class_array_ref (array_expr);
1128 1.1 mrg se.descriptor_only = 1;
1129 1.1 mrg gfc_conv_expr_descriptor (&se, array_expr);
1130 1.1 mrg array = se.expr;
1131 1.1 mrg }
1132 1.1 mrg else
1133 1.1 mrg {
1134 1.1 mrg gfc_add_data_component (array_expr);
1135 1.1 mrg gfc_conv_expr (&se, array_expr);
1136 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
1137 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
1138 1.1 mrg array = se.expr;
1139 1.1 mrg
1140 1.1 mrg if (!gfc_is_coarray (array_expr))
1141 1.1 mrg {
1142 1.1 mrg /* No copy back needed, hence set attr's allocatable/pointer
1143 1.1 mrg to zero. */
1144 1.1 mrg gfc_clear_attr (&attr);
1145 1.1 mrg gfc_init_se (&se, NULL);
1146 1.1 mrg array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1147 1.1 mrg }
1148 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
1149 1.1 mrg }
1150 1.1 mrg gfc_free_expr (array_expr);
1151 1.1 mrg }
1152 1.1 mrg
1153 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (array)))
1154 1.1 mrg array = gfc_build_addr_expr (NULL, array);
1155 1.1 mrg
1156 1.1 mrg gfc_add_block_to_block (&block, &se.pre);
1157 1.1 mrg tmp = build_call_expr_loc (input_location,
1158 1.1 mrg final_fndecl, 3, array,
1159 1.1 mrg size, fini_coarray ? boolean_true_node
1160 1.1 mrg : boolean_false_node);
1161 1.1 mrg gfc_add_block_to_block (&block, &se.post);
1162 1.1 mrg gfc_add_expr_to_block (&block, tmp);
1163 1.1 mrg return gfc_finish_block (&block);
1164 1.1 mrg }
1165 1.1 mrg
1166 1.1 mrg
1167 1.1 mrg bool
1168 1.1 mrg gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1169 1.1 mrg bool fini_coarray)
1170 1.1 mrg {
1171 1.1 mrg gfc_se se;
1172 1.1 mrg stmtblock_t block2;
1173 1.1 mrg tree final_fndecl, size, array, tmp, cond;
1174 1.1 mrg symbol_attribute attr;
1175 1.1 mrg gfc_expr *final_expr = NULL;
1176 1.1 mrg
1177 1.1 mrg if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1178 1.1 mrg return false;
1179 1.1 mrg
1180 1.1 mrg gfc_init_block (&block2);
1181 1.1 mrg
1182 1.1 mrg if (comp->ts.type == BT_DERIVED)
1183 1.1 mrg {
1184 1.1 mrg if (comp->attr.pointer)
1185 1.1 mrg return false;
1186 1.1 mrg
1187 1.1 mrg gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1188 1.1 mrg if (!final_expr)
1189 1.1 mrg return false;
1190 1.1 mrg
1191 1.1 mrg gfc_init_se (&se, NULL);
1192 1.1 mrg gfc_conv_expr (&se, final_expr);
1193 1.1 mrg final_fndecl = se.expr;
1194 1.1 mrg size = gfc_typenode_for_spec (&comp->ts);
1195 1.1 mrg size = TYPE_SIZE_UNIT (size);
1196 1.1 mrg size = fold_convert (gfc_array_index_type, size);
1197 1.1 mrg
1198 1.1 mrg array = decl;
1199 1.1 mrg }
1200 1.1 mrg else /* comp->ts.type == BT_CLASS. */
1201 1.1 mrg {
1202 1.1 mrg if (CLASS_DATA (comp)->attr.class_pointer)
1203 1.1 mrg return false;
1204 1.1 mrg
1205 1.1 mrg gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
1206 1.1 mrg final_fndecl = gfc_class_vtab_final_get (decl);
1207 1.1 mrg size = gfc_class_vtab_size_get (decl);
1208 1.1 mrg array = gfc_class_data_get (decl);
1209 1.1 mrg }
1210 1.1 mrg
1211 1.1 mrg if (comp->attr.allocatable
1212 1.1 mrg || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1213 1.1 mrg {
1214 1.1 mrg tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1215 1.1 mrg ? gfc_conv_descriptor_data_get (array) : array;
1216 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1217 1.1 mrg tmp, fold_convert (TREE_TYPE (tmp),
1218 1.1 mrg null_pointer_node));
1219 1.1 mrg }
1220 1.1 mrg else
1221 1.1 mrg cond = logical_true_node;
1222 1.1 mrg
1223 1.1 mrg if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1224 1.1 mrg {
1225 1.1 mrg gfc_clear_attr (&attr);
1226 1.1 mrg gfc_init_se (&se, NULL);
1227 1.1 mrg array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1228 1.1 mrg gfc_add_block_to_block (&block2, &se.pre);
1229 1.1 mrg gcc_assert (se.post.head == NULL_TREE);
1230 1.1 mrg }
1231 1.1 mrg
1232 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (array)))
1233 1.1 mrg array = gfc_build_addr_expr (NULL, array);
1234 1.1 mrg
1235 1.1 mrg if (!final_expr)
1236 1.1 mrg {
1237 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1238 1.1 mrg final_fndecl,
1239 1.1 mrg fold_convert (TREE_TYPE (final_fndecl),
1240 1.1 mrg null_pointer_node));
1241 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1242 1.1 mrg logical_type_node, cond, tmp);
1243 1.1 mrg }
1244 1.1 mrg
1245 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1246 1.1 mrg final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1247 1.1 mrg
1248 1.1 mrg tmp = build_call_expr_loc (input_location,
1249 1.1 mrg final_fndecl, 3, array,
1250 1.1 mrg size, fini_coarray ? boolean_true_node
1251 1.1 mrg : boolean_false_node);
1252 1.1 mrg gfc_add_expr_to_block (&block2, tmp);
1253 1.1 mrg tmp = gfc_finish_block (&block2);
1254 1.1 mrg
1255 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1256 1.1 mrg build_empty_stmt (input_location));
1257 1.1 mrg gfc_add_expr_to_block (block, tmp);
1258 1.1 mrg
1259 1.1 mrg return true;
1260 1.1 mrg }
1261 1.1 mrg
1262 1.1 mrg
1263 1.1 mrg /* Add a call to the finalizer, using the passed *expr. Returns
1264 1.1 mrg true when a finalizer call has been inserted. */
1265 1.1 mrg
1266 1.1 mrg bool
1267 1.1 mrg gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
1268 1.1 mrg {
1269 1.1 mrg tree tmp;
1270 1.1 mrg gfc_ref *ref;
1271 1.1 mrg gfc_expr *expr;
1272 1.1 mrg gfc_expr *final_expr = NULL;
1273 1.1 mrg gfc_expr *elem_size = NULL;
1274 1.1 mrg bool has_finalizer = false;
1275 1.1 mrg
1276 1.1 mrg if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1277 1.1 mrg return false;
1278 1.1 mrg
1279 1.1 mrg if (expr2->ts.type == BT_DERIVED)
1280 1.1 mrg {
1281 1.1 mrg gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
1282 1.1 mrg if (!final_expr)
1283 1.1 mrg return false;
1284 1.1 mrg }
1285 1.1 mrg
1286 1.1 mrg /* If we have a class array, we need go back to the class
1287 1.1 mrg container. */
1288 1.1 mrg expr = gfc_copy_expr (expr2);
1289 1.1 mrg
1290 1.1 mrg if (expr->ref && expr->ref->next && !expr->ref->next->next
1291 1.1 mrg && expr->ref->next->type == REF_ARRAY
1292 1.1 mrg && expr->ref->type == REF_COMPONENT
1293 1.1 mrg && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1294 1.1 mrg {
1295 1.1 mrg gfc_free_ref_list (expr->ref);
1296 1.1 mrg expr->ref = NULL;
1297 1.1 mrg }
1298 1.1 mrg else
1299 1.1 mrg for (ref = expr->ref; ref; ref = ref->next)
1300 1.1 mrg if (ref->next && ref->next->next && !ref->next->next->next
1301 1.1 mrg && ref->next->next->type == REF_ARRAY
1302 1.1 mrg && ref->next->type == REF_COMPONENT
1303 1.1 mrg && strcmp (ref->next->u.c.component->name, "_data") == 0)
1304 1.1 mrg {
1305 1.1 mrg gfc_free_ref_list (ref->next);
1306 1.1 mrg ref->next = NULL;
1307 1.1 mrg }
1308 1.1 mrg
1309 1.1 mrg if (expr->ts.type == BT_CLASS)
1310 1.1 mrg {
1311 1.1 mrg has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
1312 1.1 mrg
1313 1.1 mrg if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
1314 1.1 mrg expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1315 1.1 mrg
1316 1.1 mrg final_expr = gfc_copy_expr (expr);
1317 1.1 mrg gfc_add_vptr_component (final_expr);
1318 1.1 mrg gfc_add_final_component (final_expr);
1319 1.1 mrg
1320 1.1 mrg elem_size = gfc_copy_expr (expr);
1321 1.1 mrg gfc_add_vptr_component (elem_size);
1322 1.1 mrg gfc_add_size_component (elem_size);
1323 1.1 mrg }
1324 1.1 mrg
1325 1.1 mrg gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
1326 1.1 mrg
1327 1.1 mrg tmp = gfc_build_final_call (expr->ts, final_expr, expr,
1328 1.1 mrg false, elem_size);
1329 1.1 mrg
1330 1.1 mrg if (expr->ts.type == BT_CLASS && !has_finalizer)
1331 1.1 mrg {
1332 1.1 mrg tree cond;
1333 1.1 mrg gfc_se se;
1334 1.1 mrg
1335 1.1 mrg gfc_init_se (&se, NULL);
1336 1.1 mrg se.want_pointer = 1;
1337 1.1 mrg gfc_conv_expr (&se, final_expr);
1338 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1339 1.1 mrg se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
1340 1.1 mrg
1341 1.1 mrg /* For CLASS(*) not only sym->_vtab->_final can be NULL
1342 1.1 mrg but already sym->_vtab itself. */
1343 1.1 mrg if (UNLIMITED_POLY (expr))
1344 1.1 mrg {
1345 1.1 mrg tree cond2;
1346 1.1 mrg gfc_expr *vptr_expr;
1347 1.1 mrg
1348 1.1 mrg vptr_expr = gfc_copy_expr (expr);
1349 1.1 mrg gfc_add_vptr_component (vptr_expr);
1350 1.1 mrg
1351 1.1 mrg gfc_init_se (&se, NULL);
1352 1.1 mrg se.want_pointer = 1;
1353 1.1 mrg gfc_conv_expr (&se, vptr_expr);
1354 1.1 mrg gfc_free_expr (vptr_expr);
1355 1.1 mrg
1356 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1357 1.1 mrg se.expr,
1358 1.1 mrg build_int_cst (TREE_TYPE (se.expr), 0));
1359 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1360 1.1 mrg logical_type_node, cond2, cond);
1361 1.1 mrg }
1362 1.1 mrg
1363 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1364 1.1 mrg cond, tmp, build_empty_stmt (input_location));
1365 1.1 mrg }
1366 1.1 mrg
1367 1.1 mrg gfc_add_expr_to_block (block, tmp);
1368 1.1 mrg
1369 1.1 mrg return true;
1370 1.1 mrg }
1371 1.1 mrg
1372 1.1 mrg
1373 1.1 mrg /* User-deallocate; we emit the code directly from the front-end, and the
1374 1.1 mrg logic is the same as the previous library function:
1375 1.1 mrg
1376 1.1 mrg void
1377 1.1 mrg deallocate (void *pointer, GFC_INTEGER_4 * stat)
1378 1.1 mrg {
1379 1.1 mrg if (!pointer)
1380 1.1 mrg {
1381 1.1 mrg if (stat)
1382 1.1 mrg *stat = 1;
1383 1.1 mrg else
1384 1.1 mrg runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1385 1.1 mrg }
1386 1.1 mrg else
1387 1.1 mrg {
1388 1.1 mrg free (pointer);
1389 1.1 mrg if (stat)
1390 1.1 mrg *stat = 0;
1391 1.1 mrg }
1392 1.1 mrg }
1393 1.1 mrg
1394 1.1 mrg In this front-end version, status doesn't have to be GFC_INTEGER_4.
1395 1.1 mrg Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1396 1.1 mrg even when no status variable is passed to us (this is used for
1397 1.1 mrg unconditional deallocation generated by the front-end at end of
1398 1.1 mrg each procedure).
1399 1.1 mrg
1400 1.1 mrg If a runtime-message is possible, `expr' must point to the original
1401 1.1 mrg expression being deallocated for its locus and variable name.
1402 1.1 mrg
1403 1.1 mrg For coarrays, "pointer" must be the array descriptor and not its
1404 1.1 mrg "data" component.
1405 1.1 mrg
1406 1.1 mrg COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1407 1.1 mrg the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1408 1.1 mrg analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1409 1.1 mrg be deallocated. */
1410 1.1 mrg tree
1411 1.1 mrg gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1412 1.1 mrg tree errlen, tree label_finish,
1413 1.1 mrg bool can_fail, gfc_expr* expr,
1414 1.1 mrg int coarray_dealloc_mode, tree add_when_allocated,
1415 1.1 mrg tree caf_token)
1416 1.1 mrg {
1417 1.1 mrg stmtblock_t null, non_null;
1418 1.1 mrg tree cond, tmp, error;
1419 1.1 mrg tree status_type = NULL_TREE;
1420 1.1 mrg tree token = NULL_TREE;
1421 1.1 mrg gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1422 1.1 mrg
1423 1.1 mrg if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
1424 1.1 mrg {
1425 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
1426 1.1 mrg {
1427 1.1 mrg if (caf_token)
1428 1.1 mrg token = caf_token;
1429 1.1 mrg else
1430 1.1 mrg {
1431 1.1 mrg tree caf_type, caf_decl = pointer;
1432 1.1 mrg pointer = gfc_conv_descriptor_data_get (caf_decl);
1433 1.1 mrg caf_type = TREE_TYPE (caf_decl);
1434 1.1 mrg STRIP_NOPS (pointer);
1435 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type))
1436 1.1 mrg token = gfc_conv_descriptor_token (caf_decl);
1437 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl)
1438 1.1 mrg && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1439 1.1 mrg token = GFC_DECL_TOKEN (caf_decl);
1440 1.1 mrg else
1441 1.1 mrg {
1442 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1443 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1444 1.1 mrg != NULL_TREE);
1445 1.1 mrg token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1446 1.1 mrg }
1447 1.1 mrg }
1448 1.1 mrg
1449 1.1 mrg if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1450 1.1 mrg {
1451 1.1 mrg bool comp_ref;
1452 1.1 mrg if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1453 1.1 mrg && comp_ref)
1454 1.1 mrg caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1455 1.1 mrg // else do a deregister as set by default.
1456 1.1 mrg }
1457 1.1 mrg else
1458 1.1 mrg caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
1459 1.1 mrg }
1460 1.1 mrg else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1461 1.1 mrg pointer = gfc_conv_descriptor_data_get (pointer);
1462 1.1 mrg }
1463 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1464 1.1 mrg pointer = gfc_conv_descriptor_data_get (pointer);
1465 1.1 mrg
1466 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1467 1.1 mrg build_int_cst (TREE_TYPE (pointer), 0));
1468 1.1 mrg
1469 1.1 mrg /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1470 1.1 mrg we emit a runtime error. */
1471 1.1 mrg gfc_start_block (&null);
1472 1.1 mrg if (!can_fail)
1473 1.1 mrg {
1474 1.1 mrg tree varname;
1475 1.1 mrg
1476 1.1 mrg gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1477 1.1 mrg
1478 1.1 mrg varname = gfc_build_cstring_const (expr->symtree->name);
1479 1.1 mrg varname = gfc_build_addr_expr (pchar_type_node, varname);
1480 1.1 mrg
1481 1.1 mrg error = gfc_trans_runtime_error (true, &expr->where,
1482 1.1 mrg "Attempt to DEALLOCATE unallocated '%s'",
1483 1.1 mrg varname);
1484 1.1 mrg }
1485 1.1 mrg else
1486 1.1 mrg error = build_empty_stmt (input_location);
1487 1.1 mrg
1488 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1489 1.1 mrg {
1490 1.1 mrg tree cond2;
1491 1.1 mrg
1492 1.1 mrg status_type = TREE_TYPE (TREE_TYPE (status));
1493 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1494 1.1 mrg status, build_int_cst (TREE_TYPE (status), 0));
1495 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1496 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF,
1497 1.1 mrg status_type, status),
1498 1.1 mrg build_int_cst (status_type, 1));
1499 1.1 mrg error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1500 1.1 mrg cond2, tmp, error);
1501 1.1 mrg }
1502 1.1 mrg
1503 1.1 mrg gfc_add_expr_to_block (&null, error);
1504 1.1 mrg
1505 1.1 mrg /* When POINTER is not NULL, we free it. */
1506 1.1 mrg gfc_start_block (&non_null);
1507 1.1 mrg if (add_when_allocated)
1508 1.1 mrg gfc_add_expr_to_block (&non_null, add_when_allocated);
1509 1.1 mrg gfc_add_finalizer_call (&non_null, expr);
1510 1.1 mrg if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1511 1.1 mrg || flag_coarray != GFC_FCOARRAY_LIB)
1512 1.1 mrg {
1513 1.1 mrg tmp = build_call_expr_loc (input_location,
1514 1.1 mrg builtin_decl_explicit (BUILT_IN_FREE), 1,
1515 1.1 mrg fold_convert (pvoid_type_node, pointer));
1516 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1517 1.1 mrg gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1518 1.1 mrg 0));
1519 1.1 mrg
1520 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1521 1.1 mrg {
1522 1.1 mrg /* We set STATUS to zero if it is present. */
1523 1.1 mrg tree status_type = TREE_TYPE (TREE_TYPE (status));
1524 1.1 mrg tree cond2;
1525 1.1 mrg
1526 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1527 1.1 mrg status,
1528 1.1 mrg build_int_cst (TREE_TYPE (status), 0));
1529 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1530 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF,
1531 1.1 mrg status_type, status),
1532 1.1 mrg build_int_cst (status_type, 0));
1533 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1534 1.1 mrg gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1535 1.1 mrg tmp, build_empty_stmt (input_location));
1536 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1537 1.1 mrg }
1538 1.1 mrg }
1539 1.1 mrg else
1540 1.1 mrg {
1541 1.1 mrg tree cond2, pstat = null_pointer_node;
1542 1.1 mrg
1543 1.1 mrg if (errmsg == NULL_TREE)
1544 1.1 mrg {
1545 1.1 mrg gcc_assert (errlen == NULL_TREE);
1546 1.1 mrg errmsg = null_pointer_node;
1547 1.1 mrg errlen = build_zero_cst (integer_type_node);
1548 1.1 mrg }
1549 1.1 mrg else
1550 1.1 mrg {
1551 1.1 mrg gcc_assert (errlen != NULL_TREE);
1552 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1553 1.1 mrg errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1554 1.1 mrg }
1555 1.1 mrg
1556 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1557 1.1 mrg {
1558 1.1 mrg gcc_assert (status_type == integer_type_node);
1559 1.1 mrg pstat = status;
1560 1.1 mrg }
1561 1.1 mrg
1562 1.1 mrg token = gfc_build_addr_expr (NULL_TREE, token);
1563 1.1 mrg gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
1564 1.1 mrg tmp = build_call_expr_loc (input_location,
1565 1.1 mrg gfor_fndecl_caf_deregister, 5,
1566 1.1 mrg token, build_int_cst (integer_type_node,
1567 1.1 mrg caf_dereg_type),
1568 1.1 mrg pstat, errmsg, errlen);
1569 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1570 1.1 mrg
1571 1.1 mrg /* It guarantees memory consistency within the same segment */
1572 1.1 mrg tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1573 1.1 mrg tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1574 1.1 mrg gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1575 1.1 mrg tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1576 1.1 mrg ASM_VOLATILE_P (tmp) = 1;
1577 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1578 1.1 mrg
1579 1.1 mrg if (status != NULL_TREE)
1580 1.1 mrg {
1581 1.1 mrg tree stat = build_fold_indirect_ref_loc (input_location, status);
1582 1.1 mrg tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1583 1.1 mrg void_type_node, pointer,
1584 1.1 mrg build_int_cst (TREE_TYPE (pointer),
1585 1.1 mrg 0));
1586 1.1 mrg
1587 1.1 mrg TREE_USED (label_finish) = 1;
1588 1.1 mrg tmp = build1_v (GOTO_EXPR, label_finish);
1589 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1590 1.1 mrg stat, build_zero_cst (TREE_TYPE (stat)));
1591 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1592 1.1 mrg gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1593 1.1 mrg tmp, nullify);
1594 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1595 1.1 mrg }
1596 1.1 mrg else
1597 1.1 mrg gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1598 1.1 mrg 0));
1599 1.1 mrg }
1600 1.1 mrg
1601 1.1 mrg return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1602 1.1 mrg gfc_finish_block (&null),
1603 1.1 mrg gfc_finish_block (&non_null));
1604 1.1 mrg }
1605 1.1 mrg
1606 1.1 mrg
1607 1.1 mrg /* Generate code for deallocation of allocatable scalars (variables or
1608 1.1 mrg components). Before the object itself is freed, any allocatable
1609 1.1 mrg subcomponents are being deallocated. */
1610 1.1 mrg
1611 1.1 mrg tree
1612 1.1 mrg gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
1613 1.1 mrg bool can_fail, gfc_expr* expr,
1614 1.1 mrg gfc_typespec ts, bool coarray)
1615 1.1 mrg {
1616 1.1 mrg stmtblock_t null, non_null;
1617 1.1 mrg tree cond, tmp, error;
1618 1.1 mrg bool finalizable, comp_ref;
1619 1.1 mrg gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1620 1.1 mrg
1621 1.1 mrg if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1622 1.1 mrg && comp_ref)
1623 1.1 mrg caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1624 1.1 mrg
1625 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1626 1.1 mrg build_int_cst (TREE_TYPE (pointer), 0));
1627 1.1 mrg
1628 1.1 mrg /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1629 1.1 mrg we emit a runtime error. */
1630 1.1 mrg gfc_start_block (&null);
1631 1.1 mrg if (!can_fail)
1632 1.1 mrg {
1633 1.1 mrg tree varname;
1634 1.1 mrg
1635 1.1 mrg gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1636 1.1 mrg
1637 1.1 mrg varname = gfc_build_cstring_const (expr->symtree->name);
1638 1.1 mrg varname = gfc_build_addr_expr (pchar_type_node, varname);
1639 1.1 mrg
1640 1.1 mrg error = gfc_trans_runtime_error (true, &expr->where,
1641 1.1 mrg "Attempt to DEALLOCATE unallocated '%s'",
1642 1.1 mrg varname);
1643 1.1 mrg }
1644 1.1 mrg else
1645 1.1 mrg error = build_empty_stmt (input_location);
1646 1.1 mrg
1647 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1648 1.1 mrg {
1649 1.1 mrg tree status_type = TREE_TYPE (TREE_TYPE (status));
1650 1.1 mrg tree cond2;
1651 1.1 mrg
1652 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1653 1.1 mrg status, build_int_cst (TREE_TYPE (status), 0));
1654 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1655 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF,
1656 1.1 mrg status_type, status),
1657 1.1 mrg build_int_cst (status_type, 1));
1658 1.1 mrg error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1659 1.1 mrg cond2, tmp, error);
1660 1.1 mrg }
1661 1.1 mrg gfc_add_expr_to_block (&null, error);
1662 1.1 mrg
1663 1.1 mrg /* When POINTER is not NULL, we free it. */
1664 1.1 mrg gfc_start_block (&non_null);
1665 1.1 mrg
1666 1.1 mrg /* Free allocatable components. */
1667 1.1 mrg finalizable = gfc_add_finalizer_call (&non_null, expr);
1668 1.1 mrg if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
1669 1.1 mrg {
1670 1.1 mrg int caf_mode = coarray
1671 1.1 mrg ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
1672 1.1 mrg ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
1673 1.1 mrg | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1674 1.1 mrg | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
1675 1.1 mrg : 0;
1676 1.1 mrg if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1677 1.1 mrg tmp = gfc_conv_descriptor_data_get (pointer);
1678 1.1 mrg else
1679 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, pointer);
1680 1.1 mrg tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
1681 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1682 1.1 mrg }
1683 1.1 mrg
1684 1.1 mrg if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
1685 1.1 mrg {
1686 1.1 mrg tmp = build_call_expr_loc (input_location,
1687 1.1 mrg builtin_decl_explicit (BUILT_IN_FREE), 1,
1688 1.1 mrg fold_convert (pvoid_type_node, pointer));
1689 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1690 1.1 mrg
1691 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1692 1.1 mrg {
1693 1.1 mrg /* We set STATUS to zero if it is present. */
1694 1.1 mrg tree status_type = TREE_TYPE (TREE_TYPE (status));
1695 1.1 mrg tree cond2;
1696 1.1 mrg
1697 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1698 1.1 mrg status,
1699 1.1 mrg build_int_cst (TREE_TYPE (status), 0));
1700 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1701 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF,
1702 1.1 mrg status_type, status),
1703 1.1 mrg build_int_cst (status_type, 0));
1704 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1705 1.1 mrg cond2, tmp, build_empty_stmt (input_location));
1706 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1707 1.1 mrg }
1708 1.1 mrg }
1709 1.1 mrg else
1710 1.1 mrg {
1711 1.1 mrg tree token;
1712 1.1 mrg tree pstat = null_pointer_node;
1713 1.1 mrg gfc_se se;
1714 1.1 mrg
1715 1.1 mrg gfc_init_se (&se, NULL);
1716 1.1 mrg token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
1717 1.1 mrg gcc_assert (token != NULL_TREE);
1718 1.1 mrg
1719 1.1 mrg if (status != NULL_TREE && !integer_zerop (status))
1720 1.1 mrg {
1721 1.1 mrg gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
1722 1.1 mrg pstat = status;
1723 1.1 mrg }
1724 1.1 mrg
1725 1.1 mrg tmp = build_call_expr_loc (input_location,
1726 1.1 mrg gfor_fndecl_caf_deregister, 5,
1727 1.1 mrg token, build_int_cst (integer_type_node,
1728 1.1 mrg caf_dereg_type),
1729 1.1 mrg pstat, null_pointer_node, integer_zero_node);
1730 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1731 1.1 mrg
1732 1.1 mrg /* It guarantees memory consistency within the same segment. */
1733 1.1 mrg tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
1734 1.1 mrg tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1735 1.1 mrg gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1736 1.1 mrg tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1737 1.1 mrg ASM_VOLATILE_P (tmp) = 1;
1738 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1739 1.1 mrg
1740 1.1 mrg if (status != NULL_TREE)
1741 1.1 mrg {
1742 1.1 mrg tree stat = build_fold_indirect_ref_loc (input_location, status);
1743 1.1 mrg tree cond2;
1744 1.1 mrg
1745 1.1 mrg TREE_USED (label_finish) = 1;
1746 1.1 mrg tmp = build1_v (GOTO_EXPR, label_finish);
1747 1.1 mrg cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1748 1.1 mrg stat, build_zero_cst (TREE_TYPE (stat)));
1749 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1750 1.1 mrg gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1751 1.1 mrg tmp, build_empty_stmt (input_location));
1752 1.1 mrg gfc_add_expr_to_block (&non_null, tmp);
1753 1.1 mrg }
1754 1.1 mrg }
1755 1.1 mrg
1756 1.1 mrg return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1757 1.1 mrg gfc_finish_block (&null),
1758 1.1 mrg gfc_finish_block (&non_null));
1759 1.1 mrg }
1760 1.1 mrg
1761 1.1 mrg /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1762 1.1 mrg following pseudo-code:
1763 1.1 mrg
1764 1.1 mrg void *
1765 1.1 mrg internal_realloc (void *mem, size_t size)
1766 1.1 mrg {
1767 1.1 mrg res = realloc (mem, size);
1768 1.1 mrg if (!res && size != 0)
1769 1.1 mrg _gfortran_os_error ("Allocation would exceed memory limit");
1770 1.1 mrg
1771 1.1 mrg return res;
1772 1.1 mrg } */
1773 1.1 mrg tree
1774 1.1 mrg gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
1775 1.1 mrg {
1776 1.1 mrg tree res, nonzero, null_result, tmp;
1777 1.1 mrg tree type = TREE_TYPE (mem);
1778 1.1 mrg
1779 1.1 mrg /* Only evaluate the size once. */
1780 1.1 mrg size = save_expr (fold_convert (size_type_node, size));
1781 1.1 mrg
1782 1.1 mrg /* Create a variable to hold the result. */
1783 1.1 mrg res = gfc_create_var (type, NULL);
1784 1.1 mrg
1785 1.1 mrg /* Call realloc and check the result. */
1786 1.1 mrg tmp = build_call_expr_loc (input_location,
1787 1.1 mrg builtin_decl_explicit (BUILT_IN_REALLOC), 2,
1788 1.1 mrg fold_convert (pvoid_type_node, mem), size);
1789 1.1 mrg gfc_add_modify (block, res, fold_convert (type, tmp));
1790 1.1 mrg null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
1791 1.1 mrg res, build_int_cst (pvoid_type_node, 0));
1792 1.1 mrg nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
1793 1.1 mrg build_int_cst (size_type_node, 0));
1794 1.1 mrg null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
1795 1.1 mrg null_result, nonzero);
1796 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1797 1.1 mrg null_result,
1798 1.1 mrg trans_os_error_at (NULL,
1799 1.1 mrg "Error reallocating to %lu bytes",
1800 1.1 mrg fold_convert
1801 1.1 mrg (long_unsigned_type_node, size)),
1802 1.1 mrg build_empty_stmt (input_location));
1803 1.1 mrg gfc_add_expr_to_block (block, tmp);
1804 1.1 mrg
1805 1.1 mrg return res;
1806 1.1 mrg }
1807 1.1 mrg
1808 1.1 mrg
1809 1.1 mrg /* Add an expression to another one, either at the front or the back. */
1810 1.1 mrg
1811 1.1 mrg static void
1812 1.1 mrg add_expr_to_chain (tree* chain, tree expr, bool front)
1813 1.1 mrg {
1814 1.1 mrg if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
1815 1.1 mrg return;
1816 1.1 mrg
1817 1.1 mrg if (*chain)
1818 1.1 mrg {
1819 1.1 mrg if (TREE_CODE (*chain) != STATEMENT_LIST)
1820 1.1 mrg {
1821 1.1 mrg tree tmp;
1822 1.1 mrg
1823 1.1 mrg tmp = *chain;
1824 1.1 mrg *chain = NULL_TREE;
1825 1.1 mrg append_to_statement_list (tmp, chain);
1826 1.1 mrg }
1827 1.1 mrg
1828 1.1 mrg if (front)
1829 1.1 mrg {
1830 1.1 mrg tree_stmt_iterator i;
1831 1.1 mrg
1832 1.1 mrg i = tsi_start (*chain);
1833 1.1 mrg tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
1834 1.1 mrg }
1835 1.1 mrg else
1836 1.1 mrg append_to_statement_list (expr, chain);
1837 1.1 mrg }
1838 1.1 mrg else
1839 1.1 mrg *chain = expr;
1840 1.1 mrg }
1841 1.1 mrg
1842 1.1 mrg
1843 1.1 mrg /* Add a statement at the end of a block. */
1844 1.1 mrg
1845 1.1 mrg void
1846 1.1 mrg gfc_add_expr_to_block (stmtblock_t * block, tree expr)
1847 1.1 mrg {
1848 1.1 mrg gcc_assert (block);
1849 1.1 mrg add_expr_to_chain (&block->head, expr, false);
1850 1.1 mrg }
1851 1.1 mrg
1852 1.1 mrg
1853 1.1 mrg /* Add a statement at the beginning of a block. */
1854 1.1 mrg
1855 1.1 mrg void
1856 1.1 mrg gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
1857 1.1 mrg {
1858 1.1 mrg gcc_assert (block);
1859 1.1 mrg add_expr_to_chain (&block->head, expr, true);
1860 1.1 mrg }
1861 1.1 mrg
1862 1.1 mrg
1863 1.1 mrg /* Add a block the end of a block. */
1864 1.1 mrg
1865 1.1 mrg void
1866 1.1 mrg gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
1867 1.1 mrg {
1868 1.1 mrg gcc_assert (append);
1869 1.1 mrg gcc_assert (!append->has_scope);
1870 1.1 mrg
1871 1.1 mrg gfc_add_expr_to_block (block, append->head);
1872 1.1 mrg append->head = NULL_TREE;
1873 1.1 mrg }
1874 1.1 mrg
1875 1.1 mrg
1876 1.1 mrg /* Save the current locus. The structure may not be complete, and should
1877 1.1 mrg only be used with gfc_restore_backend_locus. */
1878 1.1 mrg
1879 1.1 mrg void
1880 1.1 mrg gfc_save_backend_locus (locus * loc)
1881 1.1 mrg {
1882 1.1 mrg loc->lb = XCNEW (gfc_linebuf);
1883 1.1 mrg loc->lb->location = input_location;
1884 1.1 mrg loc->lb->file = gfc_current_backend_file;
1885 1.1 mrg }
1886 1.1 mrg
1887 1.1 mrg
1888 1.1 mrg /* Set the current locus. */
1889 1.1 mrg
1890 1.1 mrg void
1891 1.1 mrg gfc_set_backend_locus (locus * loc)
1892 1.1 mrg {
1893 1.1 mrg gfc_current_backend_file = loc->lb->file;
1894 1.1 mrg input_location = gfc_get_location (loc);
1895 1.1 mrg }
1896 1.1 mrg
1897 1.1 mrg
1898 1.1 mrg /* Restore the saved locus. Only used in conjunction with
1899 1.1 mrg gfc_save_backend_locus, to free the memory when we are done. */
1900 1.1 mrg
1901 1.1 mrg void
1902 1.1 mrg gfc_restore_backend_locus (locus * loc)
1903 1.1 mrg {
1904 1.1 mrg /* This only restores the information captured by gfc_save_backend_locus,
1905 1.1 mrg intentionally does not use gfc_get_location. */
1906 1.1 mrg input_location = loc->lb->location;
1907 1.1 mrg gfc_current_backend_file = loc->lb->file;
1908 1.1 mrg free (loc->lb);
1909 1.1 mrg }
1910 1.1 mrg
1911 1.1 mrg
1912 1.1 mrg /* Translate an executable statement. The tree cond is used by gfc_trans_do.
1913 1.1 mrg This static function is wrapped by gfc_trans_code_cond and
1914 1.1 mrg gfc_trans_code. */
1915 1.1 mrg
1916 1.1 mrg static tree
1917 1.1 mrg trans_code (gfc_code * code, tree cond)
1918 1.1 mrg {
1919 1.1 mrg stmtblock_t block;
1920 1.1 mrg tree res;
1921 1.1 mrg
1922 1.1 mrg if (!code)
1923 1.1 mrg return build_empty_stmt (input_location);
1924 1.1 mrg
1925 1.1 mrg gfc_start_block (&block);
1926 1.1 mrg
1927 1.1 mrg /* Translate statements one by one into GENERIC trees until we reach
1928 1.1 mrg the end of this gfc_code branch. */
1929 1.1 mrg for (; code; code = code->next)
1930 1.1 mrg {
1931 1.1 mrg if (code->here != 0)
1932 1.1 mrg {
1933 1.1 mrg res = gfc_trans_label_here (code);
1934 1.1 mrg gfc_add_expr_to_block (&block, res);
1935 1.1 mrg }
1936 1.1 mrg
1937 1.1 mrg gfc_current_locus = code->loc;
1938 1.1 mrg gfc_set_backend_locus (&code->loc);
1939 1.1 mrg
1940 1.1 mrg switch (code->op)
1941 1.1 mrg {
1942 1.1 mrg case EXEC_NOP:
1943 1.1 mrg case EXEC_END_BLOCK:
1944 1.1 mrg case EXEC_END_NESTED_BLOCK:
1945 1.1 mrg case EXEC_END_PROCEDURE:
1946 1.1 mrg res = NULL_TREE;
1947 1.1 mrg break;
1948 1.1 mrg
1949 1.1 mrg case EXEC_ASSIGN:
1950 1.1 mrg res = gfc_trans_assign (code);
1951 1.1 mrg break;
1952 1.1 mrg
1953 1.1 mrg case EXEC_LABEL_ASSIGN:
1954 1.1 mrg res = gfc_trans_label_assign (code);
1955 1.1 mrg break;
1956 1.1 mrg
1957 1.1 mrg case EXEC_POINTER_ASSIGN:
1958 1.1 mrg res = gfc_trans_pointer_assign (code);
1959 1.1 mrg break;
1960 1.1 mrg
1961 1.1 mrg case EXEC_INIT_ASSIGN:
1962 1.1 mrg if (code->expr1->ts.type == BT_CLASS)
1963 1.1 mrg res = gfc_trans_class_init_assign (code);
1964 1.1 mrg else
1965 1.1 mrg res = gfc_trans_init_assign (code);
1966 1.1 mrg break;
1967 1.1 mrg
1968 1.1 mrg case EXEC_CONTINUE:
1969 1.1 mrg res = NULL_TREE;
1970 1.1 mrg break;
1971 1.1 mrg
1972 1.1 mrg case EXEC_CRITICAL:
1973 1.1 mrg res = gfc_trans_critical (code);
1974 1.1 mrg break;
1975 1.1 mrg
1976 1.1 mrg case EXEC_CYCLE:
1977 1.1 mrg res = gfc_trans_cycle (code);
1978 1.1 mrg break;
1979 1.1 mrg
1980 1.1 mrg case EXEC_EXIT:
1981 1.1 mrg res = gfc_trans_exit (code);
1982 1.1 mrg break;
1983 1.1 mrg
1984 1.1 mrg case EXEC_GOTO:
1985 1.1 mrg res = gfc_trans_goto (code);
1986 1.1 mrg break;
1987 1.1 mrg
1988 1.1 mrg case EXEC_ENTRY:
1989 1.1 mrg res = gfc_trans_entry (code);
1990 1.1 mrg break;
1991 1.1 mrg
1992 1.1 mrg case EXEC_PAUSE:
1993 1.1 mrg res = gfc_trans_pause (code);
1994 1.1 mrg break;
1995 1.1 mrg
1996 1.1 mrg case EXEC_STOP:
1997 1.1 mrg case EXEC_ERROR_STOP:
1998 1.1 mrg res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
1999 1.1 mrg break;
2000 1.1 mrg
2001 1.1 mrg case EXEC_CALL:
2002 1.1 mrg /* For MVBITS we've got the special exception that we need a
2003 1.1 mrg dependency check, too. */
2004 1.1 mrg {
2005 1.1 mrg bool is_mvbits = false;
2006 1.1 mrg
2007 1.1 mrg if (code->resolved_isym)
2008 1.1 mrg {
2009 1.1 mrg res = gfc_conv_intrinsic_subroutine (code);
2010 1.1 mrg if (res != NULL_TREE)
2011 1.1 mrg break;
2012 1.1 mrg }
2013 1.1 mrg
2014 1.1 mrg if (code->resolved_isym
2015 1.1 mrg && code->resolved_isym->id == GFC_ISYM_MVBITS)
2016 1.1 mrg is_mvbits = true;
2017 1.1 mrg
2018 1.1 mrg res = gfc_trans_call (code, is_mvbits, NULL_TREE,
2019 1.1 mrg NULL_TREE, false);
2020 1.1 mrg }
2021 1.1 mrg break;
2022 1.1 mrg
2023 1.1 mrg case EXEC_CALL_PPC:
2024 1.1 mrg res = gfc_trans_call (code, false, NULL_TREE,
2025 1.1 mrg NULL_TREE, false);
2026 1.1 mrg break;
2027 1.1 mrg
2028 1.1 mrg case EXEC_ASSIGN_CALL:
2029 1.1 mrg res = gfc_trans_call (code, true, NULL_TREE,
2030 1.1 mrg NULL_TREE, false);
2031 1.1 mrg break;
2032 1.1 mrg
2033 1.1 mrg case EXEC_RETURN:
2034 1.1 mrg res = gfc_trans_return (code);
2035 1.1 mrg break;
2036 1.1 mrg
2037 1.1 mrg case EXEC_IF:
2038 1.1 mrg res = gfc_trans_if (code);
2039 1.1 mrg break;
2040 1.1 mrg
2041 1.1 mrg case EXEC_ARITHMETIC_IF:
2042 1.1 mrg res = gfc_trans_arithmetic_if (code);
2043 1.1 mrg break;
2044 1.1 mrg
2045 1.1 mrg case EXEC_BLOCK:
2046 1.1 mrg res = gfc_trans_block_construct (code);
2047 1.1 mrg break;
2048 1.1 mrg
2049 1.1 mrg case EXEC_DO:
2050 1.1 mrg res = gfc_trans_do (code, cond);
2051 1.1 mrg break;
2052 1.1 mrg
2053 1.1 mrg case EXEC_DO_CONCURRENT:
2054 1.1 mrg res = gfc_trans_do_concurrent (code);
2055 1.1 mrg break;
2056 1.1 mrg
2057 1.1 mrg case EXEC_DO_WHILE:
2058 1.1 mrg res = gfc_trans_do_while (code);
2059 1.1 mrg break;
2060 1.1 mrg
2061 1.1 mrg case EXEC_SELECT:
2062 1.1 mrg res = gfc_trans_select (code);
2063 1.1 mrg break;
2064 1.1 mrg
2065 1.1 mrg case EXEC_SELECT_TYPE:
2066 1.1 mrg res = gfc_trans_select_type (code);
2067 1.1 mrg break;
2068 1.1 mrg
2069 1.1 mrg case EXEC_SELECT_RANK:
2070 1.1 mrg res = gfc_trans_select_rank (code);
2071 1.1 mrg break;
2072 1.1 mrg
2073 1.1 mrg case EXEC_FLUSH:
2074 1.1 mrg res = gfc_trans_flush (code);
2075 1.1 mrg break;
2076 1.1 mrg
2077 1.1 mrg case EXEC_SYNC_ALL:
2078 1.1 mrg case EXEC_SYNC_IMAGES:
2079 1.1 mrg case EXEC_SYNC_MEMORY:
2080 1.1 mrg res = gfc_trans_sync (code, code->op);
2081 1.1 mrg break;
2082 1.1 mrg
2083 1.1 mrg case EXEC_LOCK:
2084 1.1 mrg case EXEC_UNLOCK:
2085 1.1 mrg res = gfc_trans_lock_unlock (code, code->op);
2086 1.1 mrg break;
2087 1.1 mrg
2088 1.1 mrg case EXEC_EVENT_POST:
2089 1.1 mrg case EXEC_EVENT_WAIT:
2090 1.1 mrg res = gfc_trans_event_post_wait (code, code->op);
2091 1.1 mrg break;
2092 1.1 mrg
2093 1.1 mrg case EXEC_FAIL_IMAGE:
2094 1.1 mrg res = gfc_trans_fail_image (code);
2095 1.1 mrg break;
2096 1.1 mrg
2097 1.1 mrg case EXEC_FORALL:
2098 1.1 mrg res = gfc_trans_forall (code);
2099 1.1 mrg break;
2100 1.1 mrg
2101 1.1 mrg case EXEC_FORM_TEAM:
2102 1.1 mrg res = gfc_trans_form_team (code);
2103 1.1 mrg break;
2104 1.1 mrg
2105 1.1 mrg case EXEC_CHANGE_TEAM:
2106 1.1 mrg res = gfc_trans_change_team (code);
2107 1.1 mrg break;
2108 1.1 mrg
2109 1.1 mrg case EXEC_END_TEAM:
2110 1.1 mrg res = gfc_trans_end_team (code);
2111 1.1 mrg break;
2112 1.1 mrg
2113 1.1 mrg case EXEC_SYNC_TEAM:
2114 1.1 mrg res = gfc_trans_sync_team (code);
2115 1.1 mrg break;
2116 1.1 mrg
2117 1.1 mrg case EXEC_WHERE:
2118 1.1 mrg res = gfc_trans_where (code);
2119 1.1 mrg break;
2120 1.1 mrg
2121 1.1 mrg case EXEC_ALLOCATE:
2122 1.1 mrg res = gfc_trans_allocate (code);
2123 1.1 mrg break;
2124 1.1 mrg
2125 1.1 mrg case EXEC_DEALLOCATE:
2126 1.1 mrg res = gfc_trans_deallocate (code);
2127 1.1 mrg break;
2128 1.1 mrg
2129 1.1 mrg case EXEC_OPEN:
2130 1.1 mrg res = gfc_trans_open (code);
2131 1.1 mrg break;
2132 1.1 mrg
2133 1.1 mrg case EXEC_CLOSE:
2134 1.1 mrg res = gfc_trans_close (code);
2135 1.1 mrg break;
2136 1.1 mrg
2137 1.1 mrg case EXEC_READ:
2138 1.1 mrg res = gfc_trans_read (code);
2139 1.1 mrg break;
2140 1.1 mrg
2141 1.1 mrg case EXEC_WRITE:
2142 1.1 mrg res = gfc_trans_write (code);
2143 1.1 mrg break;
2144 1.1 mrg
2145 1.1 mrg case EXEC_IOLENGTH:
2146 1.1 mrg res = gfc_trans_iolength (code);
2147 1.1 mrg break;
2148 1.1 mrg
2149 1.1 mrg case EXEC_BACKSPACE:
2150 1.1 mrg res = gfc_trans_backspace (code);
2151 1.1 mrg break;
2152 1.1 mrg
2153 1.1 mrg case EXEC_ENDFILE:
2154 1.1 mrg res = gfc_trans_endfile (code);
2155 1.1 mrg break;
2156 1.1 mrg
2157 1.1 mrg case EXEC_INQUIRE:
2158 1.1 mrg res = gfc_trans_inquire (code);
2159 1.1 mrg break;
2160 1.1 mrg
2161 1.1 mrg case EXEC_WAIT:
2162 1.1 mrg res = gfc_trans_wait (code);
2163 1.1 mrg break;
2164 1.1 mrg
2165 1.1 mrg case EXEC_REWIND:
2166 1.1 mrg res = gfc_trans_rewind (code);
2167 1.1 mrg break;
2168 1.1 mrg
2169 1.1 mrg case EXEC_TRANSFER:
2170 1.1 mrg res = gfc_trans_transfer (code);
2171 1.1 mrg break;
2172 1.1 mrg
2173 1.1 mrg case EXEC_DT_END:
2174 1.1 mrg res = gfc_trans_dt_end (code);
2175 1.1 mrg break;
2176 1.1 mrg
2177 1.1 mrg case EXEC_OMP_ATOMIC:
2178 1.1 mrg case EXEC_OMP_BARRIER:
2179 1.1 mrg case EXEC_OMP_CANCEL:
2180 1.1 mrg case EXEC_OMP_CANCELLATION_POINT:
2181 1.1 mrg case EXEC_OMP_CRITICAL:
2182 1.1 mrg case EXEC_OMP_DEPOBJ:
2183 1.1 mrg case EXEC_OMP_DISTRIBUTE:
2184 1.1 mrg case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2185 1.1 mrg case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2186 1.1 mrg case EXEC_OMP_DISTRIBUTE_SIMD:
2187 1.1 mrg case EXEC_OMP_DO:
2188 1.1 mrg case EXEC_OMP_DO_SIMD:
2189 1.1 mrg case EXEC_OMP_LOOP:
2190 1.1 mrg case EXEC_OMP_ERROR:
2191 1.1 mrg case EXEC_OMP_FLUSH:
2192 1.1 mrg case EXEC_OMP_MASKED:
2193 1.1 mrg case EXEC_OMP_MASKED_TASKLOOP:
2194 1.1 mrg case EXEC_OMP_MASKED_TASKLOOP_SIMD:
2195 1.1 mrg case EXEC_OMP_MASTER:
2196 1.1 mrg case EXEC_OMP_MASTER_TASKLOOP:
2197 1.1 mrg case EXEC_OMP_MASTER_TASKLOOP_SIMD:
2198 1.1 mrg case EXEC_OMP_ORDERED:
2199 1.1 mrg case EXEC_OMP_PARALLEL:
2200 1.1 mrg case EXEC_OMP_PARALLEL_DO:
2201 1.1 mrg case EXEC_OMP_PARALLEL_DO_SIMD:
2202 1.1 mrg case EXEC_OMP_PARALLEL_LOOP:
2203 1.1 mrg case EXEC_OMP_PARALLEL_MASKED:
2204 1.1 mrg case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
2205 1.1 mrg case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
2206 1.1 mrg case EXEC_OMP_PARALLEL_MASTER:
2207 1.1 mrg case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
2208 1.1 mrg case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
2209 1.1 mrg case EXEC_OMP_PARALLEL_SECTIONS:
2210 1.1 mrg case EXEC_OMP_PARALLEL_WORKSHARE:
2211 1.1 mrg case EXEC_OMP_SCOPE:
2212 1.1 mrg case EXEC_OMP_SECTIONS:
2213 1.1 mrg case EXEC_OMP_SIMD:
2214 1.1 mrg case EXEC_OMP_SINGLE:
2215 1.1 mrg case EXEC_OMP_TARGET:
2216 1.1 mrg case EXEC_OMP_TARGET_DATA:
2217 1.1 mrg case EXEC_OMP_TARGET_ENTER_DATA:
2218 1.1 mrg case EXEC_OMP_TARGET_EXIT_DATA:
2219 1.1 mrg case EXEC_OMP_TARGET_PARALLEL:
2220 1.1 mrg case EXEC_OMP_TARGET_PARALLEL_DO:
2221 1.1 mrg case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2222 1.1 mrg case EXEC_OMP_TARGET_PARALLEL_LOOP:
2223 1.1 mrg case EXEC_OMP_TARGET_SIMD:
2224 1.1 mrg case EXEC_OMP_TARGET_TEAMS:
2225 1.1 mrg case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2226 1.1 mrg case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2227 1.1 mrg case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2228 1.1 mrg case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2229 1.1 mrg case EXEC_OMP_TARGET_TEAMS_LOOP:
2230 1.1 mrg case EXEC_OMP_TARGET_UPDATE:
2231 1.1 mrg case EXEC_OMP_TASK:
2232 1.1 mrg case EXEC_OMP_TASKGROUP:
2233 1.1 mrg case EXEC_OMP_TASKLOOP:
2234 1.1 mrg case EXEC_OMP_TASKLOOP_SIMD:
2235 1.1 mrg case EXEC_OMP_TASKWAIT:
2236 1.1 mrg case EXEC_OMP_TASKYIELD:
2237 1.1 mrg case EXEC_OMP_TEAMS:
2238 1.1 mrg case EXEC_OMP_TEAMS_DISTRIBUTE:
2239 1.1 mrg case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2240 1.1 mrg case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2241 1.1 mrg case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
2242 1.1 mrg case EXEC_OMP_TEAMS_LOOP:
2243 1.1 mrg case EXEC_OMP_WORKSHARE:
2244 1.1 mrg res = gfc_trans_omp_directive (code);
2245 1.1 mrg break;
2246 1.1 mrg
2247 1.1 mrg case EXEC_OACC_CACHE:
2248 1.1 mrg case EXEC_OACC_WAIT:
2249 1.1 mrg case EXEC_OACC_UPDATE:
2250 1.1 mrg case EXEC_OACC_LOOP:
2251 1.1 mrg case EXEC_OACC_HOST_DATA:
2252 1.1 mrg case EXEC_OACC_DATA:
2253 1.1 mrg case EXEC_OACC_KERNELS:
2254 1.1 mrg case EXEC_OACC_KERNELS_LOOP:
2255 1.1 mrg case EXEC_OACC_PARALLEL:
2256 1.1 mrg case EXEC_OACC_PARALLEL_LOOP:
2257 1.1 mrg case EXEC_OACC_SERIAL:
2258 1.1 mrg case EXEC_OACC_SERIAL_LOOP:
2259 1.1 mrg case EXEC_OACC_ENTER_DATA:
2260 1.1 mrg case EXEC_OACC_EXIT_DATA:
2261 1.1 mrg case EXEC_OACC_ATOMIC:
2262 1.1 mrg case EXEC_OACC_DECLARE:
2263 1.1 mrg res = gfc_trans_oacc_directive (code);
2264 1.1 mrg break;
2265 1.1 mrg
2266 1.1 mrg default:
2267 1.1 mrg gfc_internal_error ("gfc_trans_code(): Bad statement code");
2268 1.1 mrg }
2269 1.1 mrg
2270 1.1 mrg gfc_set_backend_locus (&code->loc);
2271 1.1 mrg
2272 1.1 mrg if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2273 1.1 mrg {
2274 1.1 mrg if (TREE_CODE (res) != STATEMENT_LIST)
2275 1.1 mrg SET_EXPR_LOCATION (res, input_location);
2276 1.1 mrg
2277 1.1 mrg /* Add the new statement to the block. */
2278 1.1 mrg gfc_add_expr_to_block (&block, res);
2279 1.1 mrg }
2280 1.1 mrg }
2281 1.1 mrg
2282 1.1 mrg /* Return the finished block. */
2283 1.1 mrg return gfc_finish_block (&block);
2284 1.1 mrg }
2285 1.1 mrg
2286 1.1 mrg
2287 1.1 mrg /* Translate an executable statement with condition, cond. The condition is
2288 1.1 mrg used by gfc_trans_do to test for IO result conditions inside implied
2289 1.1 mrg DO loops of READ and WRITE statements. See build_dt in trans-io.cc. */
2290 1.1 mrg
2291 1.1 mrg tree
2292 1.1 mrg gfc_trans_code_cond (gfc_code * code, tree cond)
2293 1.1 mrg {
2294 1.1 mrg return trans_code (code, cond);
2295 1.1 mrg }
2296 1.1 mrg
2297 1.1 mrg /* Translate an executable statement without condition. */
2298 1.1 mrg
2299 1.1 mrg tree
2300 1.1 mrg gfc_trans_code (gfc_code * code)
2301 1.1 mrg {
2302 1.1 mrg return trans_code (code, NULL_TREE);
2303 1.1 mrg }
2304 1.1 mrg
2305 1.1 mrg
2306 1.1 mrg /* This function is called after a complete program unit has been parsed
2307 1.1 mrg and resolved. */
2308 1.1 mrg
2309 1.1 mrg void
2310 1.1 mrg gfc_generate_code (gfc_namespace * ns)
2311 1.1 mrg {
2312 1.1 mrg ompws_flags = 0;
2313 1.1 mrg if (ns->is_block_data)
2314 1.1 mrg {
2315 1.1 mrg gfc_generate_block_data (ns);
2316 1.1 mrg return;
2317 1.1 mrg }
2318 1.1 mrg
2319 1.1 mrg gfc_generate_function_code (ns);
2320 1.1 mrg }
2321 1.1 mrg
2322 1.1 mrg
2323 1.1 mrg /* This function is called after a complete module has been parsed
2324 1.1 mrg and resolved. */
2325 1.1 mrg
2326 1.1 mrg void
2327 1.1 mrg gfc_generate_module_code (gfc_namespace * ns)
2328 1.1 mrg {
2329 1.1 mrg gfc_namespace *n;
2330 1.1 mrg struct module_htab_entry *entry;
2331 1.1 mrg
2332 1.1 mrg gcc_assert (ns->proc_name->backend_decl == NULL);
2333 1.1 mrg ns->proc_name->backend_decl
2334 1.1 mrg = build_decl (gfc_get_location (&ns->proc_name->declared_at),
2335 1.1 mrg NAMESPACE_DECL, get_identifier (ns->proc_name->name),
2336 1.1 mrg void_type_node);
2337 1.1 mrg entry = gfc_find_module (ns->proc_name->name);
2338 1.1 mrg if (entry->namespace_decl)
2339 1.1 mrg /* Buggy sourcecode, using a module before defining it? */
2340 1.1 mrg entry->decls->empty ();
2341 1.1 mrg entry->namespace_decl = ns->proc_name->backend_decl;
2342 1.1 mrg
2343 1.1 mrg gfc_generate_module_vars (ns);
2344 1.1 mrg
2345 1.1 mrg /* We need to generate all module function prototypes first, to allow
2346 1.1 mrg sibling calls. */
2347 1.1 mrg for (n = ns->contained; n; n = n->sibling)
2348 1.1 mrg {
2349 1.1 mrg gfc_entry_list *el;
2350 1.1 mrg
2351 1.1 mrg if (!n->proc_name)
2352 1.1 mrg continue;
2353 1.1 mrg
2354 1.1 mrg gfc_create_function_decl (n, false);
2355 1.1 mrg DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2356 1.1 mrg gfc_module_add_decl (entry, n->proc_name->backend_decl);
2357 1.1 mrg for (el = ns->entries; el; el = el->next)
2358 1.1 mrg {
2359 1.1 mrg DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2360 1.1 mrg gfc_module_add_decl (entry, el->sym->backend_decl);
2361 1.1 mrg }
2362 1.1 mrg }
2363 1.1 mrg
2364 1.1 mrg for (n = ns->contained; n; n = n->sibling)
2365 1.1 mrg {
2366 1.1 mrg if (!n->proc_name)
2367 1.1 mrg continue;
2368 1.1 mrg
2369 1.1 mrg gfc_generate_function_code (n);
2370 1.1 mrg }
2371 1.1 mrg }
2372 1.1 mrg
2373 1.1 mrg
2374 1.1 mrg /* Initialize an init/cleanup block with existing code. */
2375 1.1 mrg
2376 1.1 mrg void
2377 1.1 mrg gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2378 1.1 mrg {
2379 1.1 mrg gcc_assert (block);
2380 1.1 mrg
2381 1.1 mrg block->init = NULL_TREE;
2382 1.1 mrg block->code = code;
2383 1.1 mrg block->cleanup = NULL_TREE;
2384 1.1 mrg }
2385 1.1 mrg
2386 1.1 mrg
2387 1.1 mrg /* Add a new pair of initializers/clean-up code. */
2388 1.1 mrg
2389 1.1 mrg void
2390 1.1 mrg gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2391 1.1 mrg {
2392 1.1 mrg gcc_assert (block);
2393 1.1 mrg
2394 1.1 mrg /* The new pair of init/cleanup should be "wrapped around" the existing
2395 1.1 mrg block of code, thus the initialization is added to the front and the
2396 1.1 mrg cleanup to the back. */
2397 1.1 mrg add_expr_to_chain (&block->init, init, true);
2398 1.1 mrg add_expr_to_chain (&block->cleanup, cleanup, false);
2399 1.1 mrg }
2400 1.1 mrg
2401 1.1 mrg
2402 1.1 mrg /* Finish up a wrapped block by building a corresponding try-finally expr. */
2403 1.1 mrg
2404 1.1 mrg tree
2405 1.1 mrg gfc_finish_wrapped_block (gfc_wrapped_block* block)
2406 1.1 mrg {
2407 1.1 mrg tree result;
2408 1.1 mrg
2409 1.1 mrg gcc_assert (block);
2410 1.1 mrg
2411 1.1 mrg /* Build the final expression. For this, just add init and body together,
2412 1.1 mrg and put clean-up with that into a TRY_FINALLY_EXPR. */
2413 1.1 mrg result = block->init;
2414 1.1 mrg add_expr_to_chain (&result, block->code, false);
2415 1.1 mrg if (block->cleanup)
2416 1.1 mrg result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2417 1.1 mrg result, block->cleanup);
2418 1.1 mrg
2419 1.1 mrg /* Clear the block. */
2420 1.1 mrg block->init = NULL_TREE;
2421 1.1 mrg block->code = NULL_TREE;
2422 1.1 mrg block->cleanup = NULL_TREE;
2423 1.1 mrg
2424 1.1 mrg return result;
2425 1.1 mrg }
2426 1.1 mrg
2427 1.1 mrg
2428 1.1 mrg /* Helper function for marking a boolean expression tree as unlikely. */
2429 1.1 mrg
2430 1.1 mrg tree
2431 1.1 mrg gfc_unlikely (tree cond, enum br_predictor predictor)
2432 1.1 mrg {
2433 1.1 mrg tree tmp;
2434 1.1 mrg
2435 1.1 mrg if (optimize)
2436 1.1 mrg {
2437 1.1 mrg cond = fold_convert (long_integer_type_node, cond);
2438 1.1 mrg tmp = build_zero_cst (long_integer_type_node);
2439 1.1 mrg cond = build_call_expr_loc (input_location,
2440 1.1 mrg builtin_decl_explicit (BUILT_IN_EXPECT),
2441 1.1 mrg 3, cond, tmp,
2442 1.1 mrg build_int_cst (integer_type_node,
2443 1.1 mrg predictor));
2444 1.1 mrg }
2445 1.1 mrg return cond;
2446 1.1 mrg }
2447 1.1 mrg
2448 1.1 mrg
2449 1.1 mrg /* Helper function for marking a boolean expression tree as likely. */
2450 1.1 mrg
2451 1.1 mrg tree
2452 1.1 mrg gfc_likely (tree cond, enum br_predictor predictor)
2453 1.1 mrg {
2454 1.1 mrg tree tmp;
2455 1.1 mrg
2456 1.1 mrg if (optimize)
2457 1.1 mrg {
2458 1.1 mrg cond = fold_convert (long_integer_type_node, cond);
2459 1.1 mrg tmp = build_one_cst (long_integer_type_node);
2460 1.1 mrg cond = build_call_expr_loc (input_location,
2461 1.1 mrg builtin_decl_explicit (BUILT_IN_EXPECT),
2462 1.1 mrg 3, cond, tmp,
2463 1.1 mrg build_int_cst (integer_type_node,
2464 1.1 mrg predictor));
2465 1.1 mrg }
2466 1.1 mrg return cond;
2467 1.1 mrg }
2468 1.1 mrg
2469 1.1 mrg
2470 1.1 mrg /* Get the string length for a deferred character length component. */
2471 1.1 mrg
2472 1.1 mrg bool
2473 1.1 mrg gfc_deferred_strlen (gfc_component *c, tree *decl)
2474 1.1 mrg {
2475 1.1 mrg char name[GFC_MAX_SYMBOL_LEN+9];
2476 1.1 mrg gfc_component *strlen;
2477 1.1 mrg if (!(c->ts.type == BT_CHARACTER
2478 1.1 mrg && (c->ts.deferred || c->attr.pdt_string)))
2479 1.1 mrg return false;
2480 1.1 mrg sprintf (name, "_%s_length", c->name);
2481 1.1 mrg for (strlen = c; strlen; strlen = strlen->next)
2482 1.1 mrg if (strcmp (strlen->name, name) == 0)
2483 1.1 mrg break;
2484 1.1 mrg *decl = strlen ? strlen->backend_decl : NULL_TREE;
2485 1.1 mrg return strlen != NULL;
2486 1.1 mrg }
2487