hppa: Fix pr110279-1.c on hppa
[official-gcc.git] / gcc / fortran / trans.cc
blob961b0b5a573f372884a58c4c433f35c925acdb7a
1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
3 Contributed by Paul Brook
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "options.h"
25 #include "tree.h"
26 #include "gfortran.h"
27 #include "gimple-expr.h" /* For create_tmp_var_raw. */
28 #include "trans.h"
29 #include "stringpool.h"
30 #include "fold-const.h"
31 #include "tree-iterator.h"
32 #include "trans-stmt.h"
33 #include "trans-array.h"
34 #include "trans-types.h"
35 #include "trans-const.h"
37 /* Naming convention for backend interface code:
39 gfc_trans_* translate gfc_code into STMT trees.
41 gfc_conv_* expression conversion
43 gfc_get_* get a backend tree representation of a decl or type */
45 static gfc_file *gfc_current_backend_file;
47 const char gfc_msg_fault[] = N_("Array reference out of bounds");
50 /* Return a location_t suitable for 'tree' for a gfortran locus. The way the
51 parser works in gfortran, loc->lb->location contains only the line number
52 and LOCATION_COLUMN is 0; hence, the column has to be added when generating
53 locations for 'tree'. Cf. error.cc's gfc_format_decoder. */
55 location_t
56 gfc_get_location (locus *loc)
58 return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
59 loc->nextc - loc->lb->line);
62 /* Advance along TREE_CHAIN n times. */
64 tree
65 gfc_advance_chain (tree t, int n)
67 for (; n > 0; n--)
69 gcc_assert (t != NULL_TREE);
70 t = DECL_CHAIN (t);
72 return t;
75 static int num_var;
77 #define MAX_PREFIX_LEN 20
79 static tree
80 create_var_debug_raw (tree type, const char *prefix)
82 /* Space for prefix + "_" + 10-digit-number + \0. */
83 char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
84 tree t;
85 int i;
87 if (prefix == NULL)
88 prefix = "gfc";
89 else
90 gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
92 for (i = 0; prefix[i] != 0; i++)
93 name_buf[i] = gfc_wide_toupper (prefix[i]);
95 snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
97 t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
99 /* Not setting this causes some regressions. */
100 DECL_ARTIFICIAL (t) = 1;
102 /* We want debug info for it. */
103 DECL_IGNORED_P (t) = 0;
104 /* It should not be nameless. */
105 DECL_NAMELESS (t) = 0;
107 /* Make the variable writable. */
108 TREE_READONLY (t) = 0;
110 DECL_EXTERNAL (t) = 0;
111 TREE_STATIC (t) = 0;
112 TREE_USED (t) = 1;
114 return t;
117 /* Creates a variable declaration with a given TYPE. */
119 tree
120 gfc_create_var_np (tree type, const char *prefix)
122 tree t;
124 if (flag_debug_aux_vars)
125 return create_var_debug_raw (type, prefix);
127 t = create_tmp_var_raw (type, prefix);
129 /* No warnings for anonymous variables. */
130 if (prefix == NULL)
131 suppress_warning (t);
133 return t;
137 /* Like above, but also adds it to the current scope. */
139 tree
140 gfc_create_var (tree type, const char *prefix)
142 tree tmp;
144 tmp = gfc_create_var_np (type, prefix);
146 pushdecl (tmp);
148 return tmp;
152 /* If the expression is not constant, evaluate it now. We assign the
153 result of the expression to an artificially created variable VAR, and
154 return a pointer to the VAR_DECL node for this variable. */
156 tree
157 gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
159 tree var;
161 if (CONSTANT_CLASS_P (expr))
162 return expr;
164 var = gfc_create_var (TREE_TYPE (expr), NULL);
165 gfc_add_modify_loc (loc, pblock, var, expr);
167 return var;
171 tree
172 gfc_evaluate_now (tree expr, stmtblock_t * pblock)
174 return gfc_evaluate_now_loc (input_location, expr, pblock);
178 /* Returns a fresh pointer variable pointing to the same data as EXPR, adding
179 in BLOCK the initialization code that makes it point to EXPR. */
181 tree
182 gfc_evaluate_data_ref_now (tree expr, stmtblock_t *block)
184 tree t = expr;
186 STRIP_NOPS (t);
188 /* If EXPR can be used as lhs of an assignment, we have to take the address
189 of EXPR. Otherwise, reassigning the pointer would retarget it to some
190 other data without EXPR being retargetted as well. */
191 bool lvalue_p = DECL_P (t) || REFERENCE_CLASS_P (t) || INDIRECT_REF_P (t);
193 tree value;
194 if (lvalue_p)
196 value = gfc_build_addr_expr (NULL_TREE, expr);
197 value = gfc_evaluate_now (value, block);
198 return build_fold_indirect_ref_loc (input_location, value);
200 else
201 return gfc_evaluate_now (expr, block);
205 /* Like gfc_evaluate_now, but add the created variable to the
206 function scope. */
208 tree
209 gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
211 tree var;
212 var = gfc_create_var_np (TREE_TYPE (expr), NULL);
213 gfc_add_decl_to_function (var);
214 gfc_add_modify (pblock, var, expr);
216 return var;
219 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
220 A MODIFY_EXPR is an assignment:
221 LHS <- RHS. */
223 void
224 gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
226 tree tmp;
228 tree t1, t2;
229 t1 = TREE_TYPE (rhs);
230 t2 = TREE_TYPE (lhs);
231 /* Make sure that the types of the rhs and the lhs are compatible
232 for scalar assignments. We should probably have something
233 similar for aggregates, but right now removing that check just
234 breaks everything. */
235 gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
236 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
238 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
239 rhs);
240 gfc_add_expr_to_block (pblock, tmp);
244 void
245 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
247 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
251 /* Create a new scope/binding level and initialize a block. Care must be
252 taken when translating expressions as any temporaries will be placed in
253 the innermost scope. */
255 void
256 gfc_start_block (stmtblock_t * block)
258 /* Start a new binding level. */
259 pushlevel ();
260 block->has_scope = 1;
262 /* The block is empty. */
263 block->head = NULL_TREE;
267 /* Initialize a block without creating a new scope. */
269 void
270 gfc_init_block (stmtblock_t * block)
272 block->head = NULL_TREE;
273 block->has_scope = 0;
277 /* Sometimes we create a scope but it turns out that we don't actually
278 need it. This function merges the scope of BLOCK with its parent.
279 Only variable decls will be merged, you still need to add the code. */
281 void
282 gfc_merge_block_scope (stmtblock_t * block)
284 tree decl;
285 tree next;
287 gcc_assert (block->has_scope);
288 block->has_scope = 0;
290 /* Remember the decls in this scope. */
291 decl = getdecls ();
292 poplevel (0, 0);
294 /* Add them to the parent scope. */
295 while (decl != NULL_TREE)
297 next = DECL_CHAIN (decl);
298 DECL_CHAIN (decl) = NULL_TREE;
300 pushdecl (decl);
301 decl = next;
306 /* Finish a scope containing a block of statements. */
308 tree
309 gfc_finish_block (stmtblock_t * stmtblock)
311 tree decl;
312 tree expr;
313 tree block;
315 expr = stmtblock->head;
316 if (!expr)
317 expr = build_empty_stmt (input_location);
319 stmtblock->head = NULL_TREE;
321 if (stmtblock->has_scope)
323 decl = getdecls ();
325 if (decl)
327 block = poplevel (1, 0);
328 expr = build3_v (BIND_EXPR, decl, expr, block);
330 else
331 poplevel (0, 0);
334 return expr;
338 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
339 natural type is used. */
341 tree
342 gfc_build_addr_expr (tree type, tree t)
344 tree base_type = TREE_TYPE (t);
345 tree natural_type;
347 if (type && POINTER_TYPE_P (type)
348 && TREE_CODE (base_type) == ARRAY_TYPE
349 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
350 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
352 tree min_val = size_zero_node;
353 tree type_domain = TYPE_DOMAIN (base_type);
354 if (type_domain && TYPE_MIN_VALUE (type_domain))
355 min_val = TYPE_MIN_VALUE (type_domain);
356 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
357 t, min_val, NULL_TREE, NULL_TREE));
358 natural_type = type;
360 else
361 natural_type = build_pointer_type (base_type);
363 if (INDIRECT_REF_P (t))
365 if (!type)
366 type = natural_type;
367 t = TREE_OPERAND (t, 0);
368 natural_type = TREE_TYPE (t);
370 else
372 tree base = get_base_address (t);
373 if (base && DECL_P (base))
374 TREE_ADDRESSABLE (base) = 1;
375 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
378 if (type && natural_type != type)
379 t = convert (type, t);
381 return t;
385 static tree
386 get_array_span (tree type, tree decl)
388 tree span;
390 /* Component references are guaranteed to have a reliable value for
391 'span'. Likewise indirect references since they emerge from the
392 conversion of a CFI descriptor or the hidden dummy descriptor. */
393 if (TREE_CODE (decl) == COMPONENT_REF
394 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
395 return gfc_conv_descriptor_span_get (decl);
396 else if (INDIRECT_REF_P (decl)
397 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
398 return gfc_conv_descriptor_span_get (decl);
400 /* Return the span for deferred character length array references. */
401 if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
403 if (TREE_CODE (decl) == PARM_DECL)
404 decl = build_fold_indirect_ref_loc (input_location, decl);
405 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
406 span = gfc_conv_descriptor_span_get (decl);
407 else
408 span = gfc_get_character_len_in_bytes (type);
409 span = (span && !integer_zerop (span))
410 ? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE);
412 /* Likewise for class array or pointer array references. */
413 else if (TREE_CODE (decl) == FIELD_DECL
414 || VAR_OR_FUNCTION_DECL_P (decl)
415 || TREE_CODE (decl) == PARM_DECL)
417 if (GFC_DECL_CLASS (decl))
419 /* When a temporary is in place for the class array, then the
420 original class' declaration is stored in the saved
421 descriptor. */
422 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
423 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
424 else
426 /* Allow for dummy arguments and other good things. */
427 if (POINTER_TYPE_P (TREE_TYPE (decl)))
428 decl = build_fold_indirect_ref_loc (input_location, decl);
430 /* Check if '_data' is an array descriptor. If it is not,
431 the array must be one of the components of the class
432 object, so return a null span. */
433 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
434 gfc_class_data_get (decl))))
435 return NULL_TREE;
437 span = gfc_class_vtab_size_get (decl);
438 /* For unlimited polymorphic entities then _len component needs
439 to be multiplied with the size. */
440 span = gfc_resize_class_size_with_len (NULL, decl, span);
442 else if (GFC_DECL_PTR_ARRAY_P (decl))
444 if (TREE_CODE (decl) == PARM_DECL)
445 decl = build_fold_indirect_ref_loc (input_location, decl);
446 span = gfc_conv_descriptor_span_get (decl);
448 else
449 span = NULL_TREE;
451 else
452 span = NULL_TREE;
454 return span;
458 tree
459 gfc_build_spanned_array_ref (tree base, tree offset, tree span)
461 tree type;
462 tree tmp;
463 type = TREE_TYPE (TREE_TYPE (base));
464 offset = fold_build2_loc (input_location, MULT_EXPR,
465 gfc_array_index_type,
466 offset, span);
467 tmp = gfc_build_addr_expr (pvoid_type_node, base);
468 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
469 tmp = fold_convert (build_pointer_type (type), tmp);
470 if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
471 || !TYPE_STRING_FLAG (type))
472 tmp = build_fold_indirect_ref_loc (input_location, tmp);
473 return tmp;
477 /* Build an ARRAY_REF with its natural type.
478 NON_NEGATIVE_OFFSET indicates if it’s true that OFFSET can’t be negative,
479 and thus that an ARRAY_REF can safely be generated. If it’s false, we
480 have to play it safe and use pointer arithmetic. */
482 tree
483 gfc_build_array_ref (tree base, tree offset, tree decl,
484 bool non_negative_offset, tree vptr)
486 tree type = TREE_TYPE (base);
487 tree span = NULL_TREE;
489 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
491 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
493 return fold_convert (TYPE_MAIN_VARIANT (type), base);
496 /* Scalar coarray, there is nothing to do. */
497 if (TREE_CODE (type) != ARRAY_TYPE)
499 gcc_assert (decl == NULL_TREE);
500 gcc_assert (integer_zerop (offset));
501 return base;
504 type = TREE_TYPE (type);
506 if (DECL_P (base))
507 TREE_ADDRESSABLE (base) = 1;
509 /* Strip NON_LVALUE_EXPR nodes. */
510 STRIP_TYPE_NOPS (offset);
512 /* If decl or vptr are non-null, pointer arithmetic for the array reference
513 is likely. Generate the 'span' for the array reference. */
514 if (vptr)
516 span = gfc_vptr_size_get (vptr);
518 /* Check if this is an unlimited polymorphic object carrying a character
519 payload. In this case, the 'len' field is non-zero. */
520 if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
521 span = gfc_resize_class_size_with_len (NULL, decl, span);
523 else if (decl)
524 span = get_array_span (type, decl);
526 /* If a non-null span has been generated reference the element with
527 pointer arithmetic. */
528 if (span != NULL_TREE)
529 return gfc_build_spanned_array_ref (base, offset, span);
530 /* Else use a straightforward array reference if possible. */
531 else if (non_negative_offset)
532 return build4_loc (input_location, ARRAY_REF, type, base, offset,
533 NULL_TREE, NULL_TREE);
534 /* Otherwise use pointer arithmetic. */
535 else
537 gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
538 tree min = NULL_TREE;
539 if (TYPE_DOMAIN (TREE_TYPE (base))
540 && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
541 min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
543 tree zero_based_index
544 = min ? fold_build2_loc (input_location, MINUS_EXPR,
545 gfc_array_index_type,
546 fold_convert (gfc_array_index_type, offset),
547 fold_convert (gfc_array_index_type, min))
548 : fold_convert (gfc_array_index_type, offset);
550 tree elt_size = fold_convert (gfc_array_index_type,
551 TYPE_SIZE_UNIT (type));
553 tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
554 gfc_array_index_type,
555 zero_based_index, elt_size);
557 tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
559 tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
560 offset_bytes);
561 return build1_loc (input_location, INDIRECT_REF, type,
562 fold_convert (build_pointer_type (type), ptr));
567 /* Generate a call to print a runtime error possibly including multiple
568 arguments and a locus. */
570 static tree
571 trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
572 va_list ap)
574 stmtblock_t block;
575 tree tmp;
576 tree arg, arg2;
577 tree *argarray;
578 tree fntype;
579 char *message;
580 const char *p;
581 int line, nargs, i;
582 location_t loc;
584 /* Compute the number of extra arguments from the format string. */
585 for (p = msgid, nargs = 0; *p; p++)
586 if (*p == '%')
588 p++;
589 if (*p != '%')
590 nargs++;
593 /* The code to generate the error. */
594 gfc_start_block (&block);
596 if (where)
598 line = LOCATION_LINE (where->lb->location);
599 message = xasprintf ("At line %d of file %s", line,
600 where->lb->file->filename);
602 else
603 message = xasprintf ("In file '%s', around line %d",
604 gfc_source_file, LOCATION_LINE (input_location) + 1);
606 arg = gfc_build_addr_expr (pchar_type_node,
607 gfc_build_localized_cstring_const (message));
608 free (message);
610 message = xasprintf ("%s", _(msgid));
611 arg2 = gfc_build_addr_expr (pchar_type_node,
612 gfc_build_localized_cstring_const (message));
613 free (message);
615 /* Build the argument array. */
616 argarray = XALLOCAVEC (tree, nargs + 2);
617 argarray[0] = arg;
618 argarray[1] = arg2;
619 for (i = 0; i < nargs; i++)
620 argarray[2 + i] = va_arg (ap, tree);
622 /* Build the function call to runtime_(warning,error)_at; because of the
623 variable number of arguments, we can't use build_call_expr_loc dinput_location,
624 irectly. */
625 fntype = TREE_TYPE (errorfunc);
627 loc = where ? gfc_get_location (where) : input_location;
628 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
629 fold_build1_loc (loc, ADDR_EXPR,
630 build_pointer_type (fntype),
631 errorfunc),
632 nargs + 2, argarray);
633 gfc_add_expr_to_block (&block, tmp);
635 return gfc_finish_block (&block);
639 tree
640 gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
642 va_list ap;
643 tree result;
645 va_start (ap, msgid);
646 result = trans_runtime_error_vararg (error
647 ? gfor_fndecl_runtime_error_at
648 : gfor_fndecl_runtime_warning_at,
649 where, msgid, ap);
650 va_end (ap);
651 return result;
655 /* Generate a runtime error if COND is true. */
657 void
658 gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
659 locus * where, const char * msgid, ...)
661 va_list ap;
662 stmtblock_t block;
663 tree body;
664 tree tmp;
665 tree tmpvar = NULL;
667 if (integer_zerop (cond))
668 return;
670 if (once)
672 tmpvar = gfc_create_var (boolean_type_node, "print_warning");
673 TREE_STATIC (tmpvar) = 1;
674 DECL_INITIAL (tmpvar) = boolean_true_node;
675 gfc_add_expr_to_block (pblock, tmpvar);
678 gfc_start_block (&block);
680 /* For error, runtime_error_at already implies PRED_NORETURN. */
681 if (!error && once)
682 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
683 NOT_TAKEN));
685 /* The code to generate the error. */
686 va_start (ap, msgid);
687 gfc_add_expr_to_block (&block,
688 trans_runtime_error_vararg
689 (error ? gfor_fndecl_runtime_error_at
690 : gfor_fndecl_runtime_warning_at,
691 where, msgid, ap));
692 va_end (ap);
694 if (once)
695 gfc_add_modify (&block, tmpvar, boolean_false_node);
697 body = gfc_finish_block (&block);
699 if (integer_onep (cond))
701 gfc_add_expr_to_block (pblock, body);
703 else
705 if (once)
706 cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
707 boolean_type_node, tmpvar,
708 fold_convert (boolean_type_node, cond));
710 tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
711 cond, body,
712 build_empty_stmt (gfc_get_location (where)));
713 gfc_add_expr_to_block (pblock, tmp);
718 static tree
719 trans_os_error_at (locus* where, const char* msgid, ...)
721 va_list ap;
722 tree result;
724 va_start (ap, msgid);
725 result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
726 where, msgid, ap);
727 va_end (ap);
728 return result;
733 /* Call malloc to allocate size bytes of memory, with special conditions:
734 + if size == 0, return a malloced area of size 1,
735 + if malloc returns NULL, issue a runtime error. */
736 tree
737 gfc_call_malloc (stmtblock_t * block, tree type, tree size)
739 tree tmp, malloc_result, null_result, res, malloc_tree;
740 stmtblock_t block2;
742 /* Create a variable to hold the result. */
743 res = gfc_create_var (prvoid_type_node, NULL);
745 /* Call malloc. */
746 gfc_start_block (&block2);
748 if (size == NULL_TREE)
749 size = build_int_cst (size_type_node, 1);
751 size = fold_convert (size_type_node, size);
752 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
753 build_int_cst (size_type_node, 1));
755 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
756 gfc_add_modify (&block2, res,
757 fold_convert (prvoid_type_node,
758 build_call_expr_loc (input_location,
759 malloc_tree, 1, size)));
761 /* Optionally check whether malloc was successful. */
762 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
764 null_result = fold_build2_loc (input_location, EQ_EXPR,
765 logical_type_node, res,
766 build_int_cst (pvoid_type_node, 0));
767 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
768 null_result,
769 trans_os_error_at (NULL,
770 "Error allocating %lu bytes",
771 fold_convert
772 (long_unsigned_type_node,
773 size)),
774 build_empty_stmt (input_location));
775 gfc_add_expr_to_block (&block2, tmp);
778 malloc_result = gfc_finish_block (&block2);
779 gfc_add_expr_to_block (block, malloc_result);
781 if (type != NULL)
782 res = fold_convert (type, res);
783 return res;
787 /* Allocate memory, using an optional status argument.
789 This function follows the following pseudo-code:
791 void *
792 allocate (size_t size, integer_type stat)
794 void *newmem;
796 if (stat requested)
797 stat = 0;
799 // if cond == NULL_NULL:
800 newmem = malloc (MAX (size, 1));
801 // otherwise:
802 newmem = <cond> ? <alt_alloc> : malloc (MAX (size, 1))
803 if (newmem == NULL)
805 if (stat)
806 *stat = LIBERROR_NO_MEMORY;
807 else
808 runtime_error ("Allocation would exceed memory limit");
810 return newmem;
811 } */
812 void
813 gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
814 tree size, tree status, tree cond, tree alt_alloc,
815 tree extra_success_expr)
817 tree tmp, error_cond;
818 stmtblock_t on_error;
819 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
821 /* If successful and stat= is given, set status to 0. */
822 if (status != NULL_TREE)
823 gfc_add_expr_to_block (block,
824 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
825 status, build_int_cst (status_type, 0)));
827 /* The allocation itself. */
828 size = fold_convert (size_type_node, size);
829 tmp = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
830 size, build_int_cst (size_type_node, 1));
832 tmp = build_call_expr_loc (input_location,
833 builtin_decl_explicit (BUILT_IN_MALLOC), 1, tmp);
834 if (cond == boolean_true_node)
835 tmp = alt_alloc;
836 else if (cond)
837 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
838 alt_alloc, tmp);
840 gfc_add_modify (block, pointer, fold_convert (TREE_TYPE (pointer), tmp));
842 /* What to do in case of error. */
843 gfc_start_block (&on_error);
844 if (status != NULL_TREE)
846 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
847 build_int_cst (status_type, LIBERROR_NO_MEMORY));
848 gfc_add_expr_to_block (&on_error, tmp);
850 else
852 /* Here, os_error_at already implies PRED_NORETURN. */
853 tree lusize = fold_convert (long_unsigned_type_node, size);
854 tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
855 gfc_add_expr_to_block (&on_error, tmp);
858 error_cond = fold_build2_loc (input_location, EQ_EXPR,
859 logical_type_node, pointer,
860 build_int_cst (prvoid_type_node, 0));
861 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
862 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
863 gfc_finish_block (&on_error),
864 extra_success_expr
865 ? extra_success_expr
866 : build_empty_stmt (input_location));
868 gfc_add_expr_to_block (block, tmp);
872 /* Allocate memory, using an optional status argument.
874 This function follows the following pseudo-code:
876 void *
877 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
879 void *newmem;
881 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
882 return newmem;
883 } */
884 void
885 gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
886 tree token, tree status, tree errmsg, tree errlen,
887 gfc_coarray_regtype alloc_type)
889 tree tmp, pstat;
891 gcc_assert (token != NULL_TREE);
893 /* The allocation itself. */
894 if (status == NULL_TREE)
895 pstat = null_pointer_node;
896 else
897 pstat = gfc_build_addr_expr (NULL_TREE, status);
899 if (errmsg == NULL_TREE)
901 gcc_assert(errlen == NULL_TREE);
902 errmsg = null_pointer_node;
903 errlen = build_int_cst (integer_type_node, 0);
906 size = fold_convert (size_type_node, size);
907 tmp = build_call_expr_loc (input_location,
908 gfor_fndecl_caf_register, 7,
909 fold_build2_loc (input_location,
910 MAX_EXPR, size_type_node, size, size_one_node),
911 build_int_cst (integer_type_node, alloc_type),
912 token, gfc_build_addr_expr (pvoid_type_node, pointer),
913 pstat, errmsg, errlen);
915 gfc_add_expr_to_block (block, tmp);
917 /* It guarantees memory consistency within the same segment */
918 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
919 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
920 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
921 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
922 ASM_VOLATILE_P (tmp) = 1;
923 gfc_add_expr_to_block (block, tmp);
927 /* Generate code for an ALLOCATE statement when the argument is an
928 allocatable variable. If the variable is currently allocated, it is an
929 error to allocate it again.
931 This function follows the following pseudo-code:
933 void *
934 allocate_allocatable (void *mem, size_t size, integer_type stat)
936 if (mem == NULL)
937 return allocate (size, stat);
938 else
940 if (stat)
941 stat = LIBERROR_ALLOCATION;
942 else
943 runtime_error ("Attempting to allocate already allocated variable");
947 expr must be set to the original expression being allocated for its locus
948 and variable name in case a runtime error has to be printed. */
949 void
950 gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
951 tree token, tree status, tree errmsg, tree errlen,
952 tree label_finish, gfc_expr* expr, int corank,
953 tree cond, tree alt_alloc, tree extra_success_expr)
955 stmtblock_t alloc_block;
956 tree tmp, null_mem, alloc, error;
957 tree type = TREE_TYPE (mem);
958 symbol_attribute caf_attr;
959 bool need_assign = false, refs_comp = false;
960 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
962 size = fold_convert (size_type_node, size);
963 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
964 logical_type_node, mem,
965 build_int_cst (type, 0)),
966 PRED_FORTRAN_REALLOC);
968 /* If mem is NULL, we call gfc_allocate_using_malloc or
969 gfc_allocate_using_lib. */
970 gfc_start_block (&alloc_block);
972 if (flag_coarray == GFC_FCOARRAY_LIB)
973 caf_attr = gfc_caf_attr (expr, true, &refs_comp);
975 if (flag_coarray == GFC_FCOARRAY_LIB
976 && (corank > 0 || caf_attr.codimension))
978 tree cond2, sub_caf_tree;
979 gfc_se se;
980 bool compute_special_caf_types_size = false;
982 if (expr->ts.type == BT_DERIVED
983 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
984 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
986 compute_special_caf_types_size = true;
987 caf_alloc_type = GFC_CAF_LOCK_ALLOC;
989 else if (expr->ts.type == BT_DERIVED
990 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
991 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
993 compute_special_caf_types_size = true;
994 caf_alloc_type = GFC_CAF_EVENT_ALLOC;
996 else if (!caf_attr.coarray_comp && refs_comp)
997 /* Only allocatable components in a derived type coarray can be
998 allocate only. */
999 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
1001 gfc_init_se (&se, NULL);
1002 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
1003 if (sub_caf_tree == NULL_TREE)
1004 sub_caf_tree = token;
1006 /* When mem is an array ref, then strip the .data-ref. */
1007 if (TREE_CODE (mem) == COMPONENT_REF
1008 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
1009 tmp = TREE_OPERAND (mem, 0);
1010 else
1011 tmp = mem;
1013 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
1014 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
1015 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1017 symbol_attribute attr;
1019 gfc_clear_attr (&attr);
1020 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
1021 need_assign = true;
1023 gfc_add_block_to_block (&alloc_block, &se.pre);
1025 /* In the front end, we represent the lock variable as pointer. However,
1026 the FE only passes the pointer around and leaves the actual
1027 representation to the library. Hence, we have to convert back to the
1028 number of elements. */
1029 if (compute_special_caf_types_size)
1030 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
1031 size, TYPE_SIZE_UNIT (ptr_type_node));
1033 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
1034 status, errmsg, errlen, caf_alloc_type);
1035 if (need_assign)
1036 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
1037 gfc_conv_descriptor_data_get (tmp)));
1038 if (status != NULL_TREE)
1040 TREE_USED (label_finish) = 1;
1041 tmp = build1_v (GOTO_EXPR, label_finish);
1042 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1043 status, build_zero_cst (TREE_TYPE (status)));
1044 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1045 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1046 tmp, build_empty_stmt (input_location));
1047 gfc_add_expr_to_block (&alloc_block, tmp);
1050 else
1051 gfc_allocate_using_malloc (&alloc_block, mem, size, status,
1052 cond, alt_alloc, extra_success_expr);
1054 alloc = gfc_finish_block (&alloc_block);
1056 /* If mem is not NULL, we issue a runtime error or set the
1057 status variable. */
1058 if (expr)
1060 tree varname;
1062 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
1063 varname = gfc_build_cstring_const (expr->symtree->name);
1064 varname = gfc_build_addr_expr (pchar_type_node, varname);
1066 error = gfc_trans_runtime_error (true, &expr->where,
1067 "Attempting to allocate already"
1068 " allocated variable '%s'",
1069 varname);
1071 else
1072 error = gfc_trans_runtime_error (true, NULL,
1073 "Attempting to allocate already allocated"
1074 " variable");
1076 if (status != NULL_TREE)
1078 tree status_type = TREE_TYPE (status);
1080 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1081 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
1084 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
1085 error, alloc);
1086 gfc_add_expr_to_block (block, tmp);
1090 /* Free a given variable. */
1092 tree
1093 gfc_call_free (tree var)
1095 return build_call_expr_loc (input_location,
1096 builtin_decl_explicit (BUILT_IN_FREE),
1097 1, fold_convert (pvoid_type_node, var));
1101 /* Generate the data reference to the finalization procedure pointer associated
1102 with the expression passed as argument in EXPR. */
1104 static void
1105 get_final_proc_ref (gfc_se *se, gfc_expr *expr, tree class_container)
1107 gfc_expr *final_wrapper = NULL;
1109 gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS);
1111 bool using_class_container = false;
1112 if (expr->ts.type == BT_DERIVED)
1113 gfc_is_finalizable (expr->ts.u.derived, &final_wrapper);
1114 else if (class_container)
1116 using_class_container = true;
1117 se->expr = gfc_class_vtab_final_get (class_container);
1119 else
1121 final_wrapper = gfc_copy_expr (expr);
1122 gfc_add_vptr_component (final_wrapper);
1123 gfc_add_final_component (final_wrapper);
1126 if (!using_class_container)
1128 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1130 gfc_conv_expr (se, final_wrapper);
1133 if (POINTER_TYPE_P (TREE_TYPE (se->expr)))
1134 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
1138 /* Generate the code to obtain the value of the element size of the expression
1139 passed as argument in EXPR. */
1141 static void
1142 get_elem_size (gfc_se *se, gfc_expr *expr, tree class_container)
1144 gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS);
1146 if (expr->ts.type == BT_DERIVED)
1148 se->expr = gfc_typenode_for_spec (&expr->ts);
1149 se->expr = TYPE_SIZE_UNIT (se->expr);
1150 se->expr = fold_convert (gfc_array_index_type, se->expr);
1152 else if (class_container)
1153 se->expr = gfc_class_vtab_size_get (class_container);
1154 else
1156 gfc_expr *class_size = gfc_copy_expr (expr);
1157 gfc_add_vptr_component (class_size);
1158 gfc_add_size_component (class_size);
1160 gfc_conv_expr (se, class_size);
1161 gcc_assert (se->post.head == NULL_TREE);
1166 /* Generate the data reference (array) descriptor corresponding to the
1167 expression passed as argument in VAR. */
1169 static void
1170 get_var_descr (gfc_se *se, gfc_expr *var, tree class_container)
1172 gfc_se tmp_se;
1174 gcc_assert (var);
1176 gfc_init_se (&tmp_se, NULL);
1178 if (var->ts.type == BT_DERIVED)
1180 tmp_se.want_pointer = 1;
1181 if (var->rank)
1183 tmp_se.descriptor_only = 1;
1184 gfc_conv_expr_descriptor (&tmp_se, var);
1186 else
1187 gfc_conv_expr (&tmp_se, var);
1189 else if (class_container)
1190 tmp_se.expr = gfc_class_data_get (class_container);
1191 else
1193 gfc_expr *array_expr;
1195 array_expr = gfc_copy_expr (var);
1197 tmp_se.want_pointer = 1;
1198 if (array_expr->rank)
1200 gfc_add_class_array_ref (array_expr);
1201 tmp_se.descriptor_only = 1;
1202 gfc_conv_expr_descriptor (&tmp_se, array_expr);
1204 else
1206 gfc_add_data_component (array_expr);
1207 gfc_conv_expr (&tmp_se, array_expr);
1208 gcc_assert (tmp_se.post.head == NULL_TREE);
1210 gfc_free_expr (array_expr);
1213 if (var->rank == 0)
1215 if (var->ts.type == BT_DERIVED
1216 || !gfc_is_coarray (var))
1218 /* No copy back needed, hence set attr's allocatable/pointer
1219 to zero. */
1220 symbol_attribute attr;
1221 gfc_clear_attr (&attr);
1222 tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr,
1223 attr);
1225 gcc_assert (tmp_se.post.head == NULL_TREE);
1228 if (!POINTER_TYPE_P (TREE_TYPE (tmp_se.expr)))
1229 tmp_se.expr = gfc_build_addr_expr (NULL, tmp_se.expr);
1231 gfc_add_block_to_block (&se->pre, &tmp_se.pre);
1232 gfc_add_block_to_block (&se->post, &tmp_se.post);
1233 se->expr = tmp_se.expr;
1237 static void
1238 get_vptr (gfc_se *se, gfc_expr *expr, tree class_container)
1240 if (class_container)
1241 se->expr = gfc_class_vptr_get (class_container);
1242 else
1244 gfc_expr *vptr_expr = gfc_copy_expr (expr);
1245 gfc_add_vptr_component (vptr_expr);
1247 gfc_se tmp_se;
1248 gfc_init_se (&tmp_se, NULL);
1249 tmp_se.want_pointer = 1;
1250 gfc_conv_expr (&tmp_se, vptr_expr);
1251 gfc_free_expr (vptr_expr);
1253 gfc_add_block_to_block (&se->pre, &tmp_se.pre);
1254 gfc_add_block_to_block (&se->post, &tmp_se.post);
1255 se->expr = tmp_se.expr;
1260 bool
1261 gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1262 bool fini_coarray)
1264 gfc_se se;
1265 stmtblock_t block2;
1266 tree final_fndecl, size, array, tmp, cond;
1267 symbol_attribute attr;
1268 gfc_expr *final_expr = NULL;
1270 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1271 return false;
1273 gfc_init_block (&block2);
1275 if (comp->ts.type == BT_DERIVED)
1277 if (comp->attr.pointer)
1278 return false;
1280 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1281 if (!final_expr)
1282 return false;
1284 gfc_init_se (&se, NULL);
1285 gfc_conv_expr (&se, final_expr);
1286 final_fndecl = se.expr;
1287 size = gfc_typenode_for_spec (&comp->ts);
1288 size = TYPE_SIZE_UNIT (size);
1289 size = fold_convert (gfc_array_index_type, size);
1291 array = decl;
1293 else /* comp->ts.type == BT_CLASS. */
1295 if (CLASS_DATA (comp)->attr.class_pointer)
1296 return false;
1298 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
1299 final_fndecl = gfc_class_vtab_final_get (decl);
1300 size = gfc_class_vtab_size_get (decl);
1301 array = gfc_class_data_get (decl);
1304 if (comp->attr.allocatable
1305 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1307 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1308 ? gfc_conv_descriptor_data_get (array) : array;
1309 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1310 tmp, fold_convert (TREE_TYPE (tmp),
1311 null_pointer_node));
1313 else
1314 cond = logical_true_node;
1316 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1318 gfc_clear_attr (&attr);
1319 gfc_init_se (&se, NULL);
1320 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1321 gfc_add_block_to_block (&block2, &se.pre);
1322 gcc_assert (se.post.head == NULL_TREE);
1325 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1326 array = gfc_build_addr_expr (NULL, array);
1328 if (!final_expr)
1330 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1331 final_fndecl,
1332 fold_convert (TREE_TYPE (final_fndecl),
1333 null_pointer_node));
1334 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1335 logical_type_node, cond, tmp);
1338 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1339 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1341 tmp = build_call_expr_loc (input_location,
1342 final_fndecl, 3, array,
1343 size, fini_coarray ? boolean_true_node
1344 : boolean_false_node);
1345 gfc_add_expr_to_block (&block2, tmp);
1346 tmp = gfc_finish_block (&block2);
1348 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1349 build_empty_stmt (input_location));
1350 gfc_add_expr_to_block (block, tmp);
1352 return true;
1356 /* Add a call to the finalizer, using the passed *expr. Returns
1357 true when a finalizer call has been inserted. */
1359 bool
1360 gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2,
1361 tree class_container)
1363 tree tmp;
1364 gfc_ref *ref;
1365 gfc_expr *expr;
1367 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1368 return false;
1370 /* Finalization of these temporaries is made by explicit calls in
1371 resolve.cc(generate_component_assignments). */
1372 if (expr2->expr_type == EXPR_VARIABLE
1373 && expr2->symtree->n.sym->name[0] == '_'
1374 && expr2->ts.type == BT_DERIVED
1375 && expr2->ts.u.derived->attr.defined_assign_comp)
1376 return false;
1378 if (expr2->ts.type == BT_DERIVED
1379 && !gfc_is_finalizable (expr2->ts.u.derived, NULL))
1380 return false;
1382 /* If we have a class array, we need go back to the class
1383 container. */
1384 expr = gfc_copy_expr (expr2);
1386 if (expr->ref && expr->ref->next && !expr->ref->next->next
1387 && expr->ref->next->type == REF_ARRAY
1388 && expr->ref->type == REF_COMPONENT
1389 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1391 gfc_free_ref_list (expr->ref);
1392 expr->ref = NULL;
1394 else
1395 for (ref = expr->ref; ref; ref = ref->next)
1396 if (ref->next && ref->next->next && !ref->next->next->next
1397 && ref->next->next->type == REF_ARRAY
1398 && ref->next->type == REF_COMPONENT
1399 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1401 gfc_free_ref_list (ref->next);
1402 ref->next = NULL;
1405 if (expr->ts.type == BT_CLASS
1406 && !expr2->rank
1407 && !expr2->ref
1408 && CLASS_DATA (expr2->symtree->n.sym)->as)
1409 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1411 stmtblock_t tmp_block;
1412 gfc_start_block (&tmp_block);
1414 gfc_se final_se;
1415 gfc_init_se (&final_se, NULL);
1416 get_final_proc_ref (&final_se, expr, class_container);
1417 gfc_add_block_to_block (block, &final_se.pre);
1419 gfc_se size_se;
1420 gfc_init_se (&size_se, NULL);
1421 get_elem_size (&size_se, expr, class_container);
1422 gfc_add_block_to_block (&tmp_block, &size_se.pre);
1424 gfc_se desc_se;
1425 gfc_init_se (&desc_se, NULL);
1426 get_var_descr (&desc_se, expr, class_container);
1427 gfc_add_block_to_block (&tmp_block, &desc_se.pre);
1429 tmp = build_call_expr_loc (input_location, final_se.expr, 3,
1430 desc_se.expr, size_se.expr,
1431 boolean_false_node);
1433 gfc_add_expr_to_block (&tmp_block, tmp);
1435 gfc_add_block_to_block (&tmp_block, &desc_se.post);
1436 gfc_add_block_to_block (&tmp_block, &size_se.post);
1438 tmp = gfc_finish_block (&tmp_block);
1440 if (expr->ts.type == BT_CLASS
1441 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
1443 tree cond;
1445 tree ptr = gfc_build_addr_expr (NULL_TREE, final_se.expr);
1447 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1448 ptr, build_int_cst (TREE_TYPE (ptr), 0));
1450 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1451 but already sym->_vtab itself. */
1452 if (UNLIMITED_POLY (expr))
1454 tree cond2;
1455 gfc_se vptr_se;
1457 gfc_init_se (&vptr_se, NULL);
1458 get_vptr (&vptr_se, expr, class_container);
1460 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1461 vptr_se.expr,
1462 build_int_cst (TREE_TYPE (vptr_se.expr), 0));
1463 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1464 logical_type_node, cond2, cond);
1467 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1468 cond, tmp, build_empty_stmt (input_location));
1471 gfc_add_expr_to_block (block, tmp);
1472 gfc_add_block_to_block (block, &final_se.post);
1474 return true;
1478 /* F2018 (7.5.6.3): "When an intrinsic assignment statement is executed
1479 (10.2.1.3), if the variable is not an unallocated allocatable variable,
1480 it is finalized after evaluation of expr and before the definition of
1481 the variable. If the variable is an allocated allocatable variable, or
1482 has an allocated allocatable subobject, that would be deallocated by
1483 intrinsic assignment, the finalization occurs before the deallocation */
1485 bool
1486 gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag)
1488 symbol_attribute lhs_attr;
1489 tree final_expr;
1490 tree ptr;
1491 tree cond;
1492 gfc_se se;
1493 gfc_symbol *sym = expr1->symtree->n.sym;
1494 gfc_ref *ref = expr1->ref;
1495 stmtblock_t final_block;
1496 gfc_init_block (&final_block);
1497 gfc_expr *finalize_expr;
1498 bool class_array_ref;
1500 /* We have to exclude vtable procedures (_copy and _final especially), uses
1501 of gfc_trans_assignment_1 in initialization and allocation before trying
1502 to build a final call. */
1503 if (!expr1->must_finalize
1504 || sym->attr.artificial
1505 || sym->ns->proc_name->attr.artificial
1506 || init_flag)
1507 return false;
1509 class_array_ref = ref && ref->type == REF_COMPONENT
1510 && !strcmp (ref->u.c.component->name, "_data")
1511 && ref->next && ref->next->type == REF_ARRAY
1512 && !ref->next->next;
1514 if (class_array_ref)
1516 finalize_expr = gfc_lval_expr_from_sym (sym);
1517 finalize_expr->must_finalize = 1;
1518 ref = NULL;
1520 else
1521 finalize_expr = gfc_copy_expr (expr1);
1523 /* F2018 7.5.6.2: Only finalizable entities are finalized. */
1524 if (!(expr1->ts.type == BT_DERIVED
1525 && gfc_is_finalizable (expr1->ts.u.derived, NULL))
1526 && expr1->ts.type != BT_CLASS)
1527 return false;
1529 if (!gfc_may_be_finalized (sym->ts))
1530 return false;
1532 gfc_init_block (&final_block);
1533 bool finalizable = gfc_add_finalizer_call (&final_block, finalize_expr);
1534 gfc_free_expr (finalize_expr);
1536 if (!finalizable)
1537 return false;
1539 lhs_attr = gfc_expr_attr (expr1);
1541 /* Check allocatable/pointer is allocated/associated. */
1542 if (lhs_attr.allocatable || lhs_attr.pointer)
1544 if (expr1->ts.type == BT_CLASS)
1546 ptr = gfc_get_class_from_gfc_expr (expr1);
1547 gcc_assert (ptr != NULL_TREE);
1548 ptr = gfc_class_data_get (ptr);
1549 if (lhs_attr.dimension)
1550 ptr = gfc_conv_descriptor_data_get (ptr);
1552 else
1554 gfc_init_se (&se, NULL);
1555 if (expr1->rank)
1557 gfc_conv_expr_descriptor (&se, expr1);
1558 ptr = gfc_conv_descriptor_data_get (se.expr);
1560 else
1562 gfc_conv_expr (&se, expr1);
1563 ptr = gfc_build_addr_expr (NULL_TREE, se.expr);
1567 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1568 ptr, build_zero_cst (TREE_TYPE (ptr)));
1569 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1570 cond, gfc_finish_block (&final_block),
1571 build_empty_stmt (input_location));
1573 else
1574 final_expr = gfc_finish_block (&final_block);
1576 /* Check optional present. */
1577 if (sym->attr.optional)
1579 cond = gfc_conv_expr_present (sym);
1580 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1581 cond, final_expr,
1582 build_empty_stmt (input_location));
1585 gfc_add_expr_to_block (&lse->finalblock, final_expr);
1587 return true;
1591 /* Finalize a TREE expression using the finalizer wrapper. The result is
1592 fixed in order to prevent repeated calls. */
1594 void
1595 gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
1596 symbol_attribute attr, int rank)
1598 tree vptr, final_fndecl, desc, tmp, size, is_final;
1599 tree data_ptr, data_null, cond;
1600 gfc_symbol *vtab;
1601 gfc_se post_se;
1602 bool is_class = GFC_CLASS_TYPE_P (TREE_TYPE (se->expr));
1604 if (attr.pointer)
1605 return;
1607 /* Derived type function results with components that have defined
1608 assignements are handled in resolve.cc(generate_component_assignments) */
1609 if (derived && (derived->attr.is_c_interop
1610 || derived->attr.is_iso_c
1611 || derived->attr.is_bind_c
1612 || derived->attr.defined_assign_comp))
1613 return;
1615 if (is_class)
1617 if (!VAR_P (se->expr))
1619 desc = gfc_evaluate_now (se->expr, &se->pre);
1620 se->expr = desc;
1622 desc = gfc_class_data_get (se->expr);
1623 vptr = gfc_class_vptr_get (se->expr);
1625 else if (derived && gfc_is_finalizable (derived, NULL))
1627 if (derived->attr.zero_comp && !rank)
1629 /* Any attempt to assign zero length entities, causes the gimplifier
1630 all manner of problems. Instead, a variable is created to act as
1631 as the argument for the final call. */
1632 desc = gfc_create_var (TREE_TYPE (se->expr), "zero");
1634 else if (se->direct_byref)
1636 desc = gfc_evaluate_now (se->expr, &se->finalblock);
1637 if (derived->attr.alloc_comp)
1639 /* Need to copy allocated components and not finalize. */
1640 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1641 gfc_add_expr_to_block (&se->finalblock, tmp);
1644 else
1646 desc = gfc_evaluate_now (se->expr, &se->pre);
1647 se->expr = gfc_evaluate_now (desc, &se->pre);
1648 if (derived->attr.alloc_comp)
1650 /* Need to copy allocated components and not finalize. */
1651 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1652 gfc_add_expr_to_block (&se->pre, tmp);
1656 vtab = gfc_find_derived_vtab (derived);
1657 if (vtab->backend_decl == NULL_TREE)
1658 vptr = gfc_get_symbol_decl (vtab);
1659 else
1660 vptr = vtab->backend_decl;
1661 vptr = gfc_build_addr_expr (NULL, vptr);
1663 else
1664 return;
1666 size = gfc_vptr_size_get (vptr);
1667 final_fndecl = gfc_vptr_final_get (vptr);
1668 is_final = fold_build2_loc (input_location, NE_EXPR,
1669 logical_type_node,
1670 final_fndecl,
1671 fold_convert (TREE_TYPE (final_fndecl),
1672 null_pointer_node));
1674 final_fndecl = build_fold_indirect_ref_loc (input_location,
1675 final_fndecl);
1676 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
1678 if (is_class)
1679 desc = gfc_conv_scalar_to_descriptor (se, desc, attr);
1680 else
1682 gfc_init_se (&post_se, NULL);
1683 desc = gfc_conv_scalar_to_descriptor (&post_se, desc, attr);
1684 gfc_add_expr_to_block (&se->pre, gfc_finish_block (&post_se.pre));
1688 if (derived && derived->attr.zero_comp)
1690 /* All the conditions below break down for zero length derived types. */
1691 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1692 gfc_build_addr_expr (NULL, desc),
1693 size, boolean_false_node);
1694 gfc_add_expr_to_block (&se->finalblock, tmp);
1695 return;
1698 if (!VAR_P (desc))
1700 tmp = gfc_create_var (TREE_TYPE (desc), "res");
1701 if (se->direct_byref)
1702 gfc_add_modify (&se->finalblock, tmp, desc);
1703 else
1704 gfc_add_modify (&se->pre, tmp, desc);
1705 desc = tmp;
1708 data_ptr = gfc_conv_descriptor_data_get (desc);
1709 data_null = fold_convert (TREE_TYPE (data_ptr), null_pointer_node);
1710 cond = fold_build2_loc (input_location, NE_EXPR,
1711 logical_type_node, data_ptr, data_null);
1712 is_final = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1713 logical_type_node, is_final, cond);
1714 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1715 gfc_build_addr_expr (NULL, desc),
1716 size, boolean_false_node);
1717 tmp = fold_build3_loc (input_location, COND_EXPR,
1718 void_type_node, is_final, tmp,
1719 build_empty_stmt (input_location));
1721 if (is_class && se->ss && se->ss->loop)
1723 gfc_add_expr_to_block (&se->loop->post, tmp);
1724 tmp = fold_build3_loc (input_location, COND_EXPR,
1725 void_type_node, cond,
1726 gfc_call_free (data_ptr),
1727 build_empty_stmt (input_location));
1728 gfc_add_expr_to_block (&se->loop->post, tmp);
1729 gfc_add_modify (&se->loop->post, data_ptr, data_null);
1731 else
1733 gfc_add_expr_to_block (&se->finalblock, tmp);
1735 /* Let the scalarizer take care of freeing of temporary arrays. */
1736 if (attr.allocatable && !(se->loop && se->loop->temp_dim))
1738 tmp = fold_build3_loc (input_location, COND_EXPR,
1739 void_type_node, cond,
1740 gfc_call_free (data_ptr),
1741 build_empty_stmt (input_location));
1742 gfc_add_expr_to_block (&se->finalblock, tmp);
1743 gfc_add_modify (&se->finalblock, data_ptr, data_null);
1749 /* User-deallocate; we emit the code directly from the front-end, and the
1750 logic is the same as the previous library function:
1752 void
1753 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1755 if (!pointer)
1757 if (stat)
1758 *stat = 1;
1759 else
1760 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1762 else
1764 free (pointer);
1765 if (stat)
1766 *stat = 0;
1770 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1771 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1772 even when no status variable is passed to us (this is used for
1773 unconditional deallocation generated by the front-end at end of
1774 each procedure).
1776 If a runtime-message is possible, `expr' must point to the original
1777 expression being deallocated for its locus and variable name.
1779 For coarrays, "pointer" must be the array descriptor and not its
1780 "data" component.
1782 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1783 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1784 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1785 be deallocated. */
1786 tree
1787 gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1788 tree errlen, tree label_finish,
1789 bool can_fail, gfc_expr* expr,
1790 int coarray_dealloc_mode, tree class_container,
1791 tree add_when_allocated, tree caf_token)
1793 stmtblock_t null, non_null;
1794 tree cond, tmp, error;
1795 tree status_type = NULL_TREE;
1796 tree token = NULL_TREE;
1797 tree descr = NULL_TREE;
1798 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1800 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
1802 if (flag_coarray == GFC_FCOARRAY_LIB)
1804 if (caf_token)
1806 token = caf_token;
1807 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1808 pointer = gfc_conv_descriptor_data_get (pointer);
1810 else
1812 tree caf_type, caf_decl = pointer;
1813 pointer = gfc_conv_descriptor_data_get (caf_decl);
1814 caf_type = TREE_TYPE (caf_decl);
1815 STRIP_NOPS (pointer);
1816 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
1817 token = gfc_conv_descriptor_token (caf_decl);
1818 else if (DECL_LANG_SPECIFIC (caf_decl)
1819 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1820 token = GFC_DECL_TOKEN (caf_decl);
1821 else
1823 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1824 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1825 != NULL_TREE);
1826 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1830 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1832 bool comp_ref;
1833 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1834 && comp_ref)
1835 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1836 // else do a deregister as set by default.
1838 else
1839 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
1841 else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1842 pointer = gfc_conv_descriptor_data_get (pointer);
1844 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1846 descr = pointer;
1847 pointer = gfc_conv_descriptor_data_get (pointer);
1850 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1851 build_int_cst (TREE_TYPE (pointer), 0));
1853 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1854 we emit a runtime error. */
1855 gfc_start_block (&null);
1856 if (!can_fail)
1858 tree varname;
1860 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1862 varname = gfc_build_cstring_const (expr->symtree->name);
1863 varname = gfc_build_addr_expr (pchar_type_node, varname);
1865 error = gfc_trans_runtime_error (true, &expr->where,
1866 "Attempt to DEALLOCATE unallocated '%s'",
1867 varname);
1869 else
1870 error = build_empty_stmt (input_location);
1872 if (status != NULL_TREE && !integer_zerop (status))
1874 tree cond2;
1876 status_type = TREE_TYPE (TREE_TYPE (status));
1877 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1878 status, build_int_cst (TREE_TYPE (status), 0));
1879 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1880 fold_build1_loc (input_location, INDIRECT_REF,
1881 status_type, status),
1882 build_int_cst (status_type, 1));
1883 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1884 cond2, tmp, error);
1887 gfc_add_expr_to_block (&null, error);
1889 /* When POINTER is not NULL, we free it. */
1890 gfc_start_block (&non_null);
1891 if (add_when_allocated)
1892 gfc_add_expr_to_block (&non_null, add_when_allocated);
1893 gfc_add_finalizer_call (&non_null, expr, class_container);
1894 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1895 || flag_coarray != GFC_FCOARRAY_LIB)
1897 tmp = build_call_expr_loc (input_location,
1898 builtin_decl_explicit (BUILT_IN_FREE), 1,
1899 fold_convert (pvoid_type_node, pointer));
1900 if (flag_openmp_allocators && coarray_dealloc_mode < GFC_CAF_COARRAY_ANALYZE)
1902 tree cond, omp_tmp;
1903 if (descr)
1904 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1905 gfc_conv_descriptor_version (descr),
1906 build_int_cst (integer_type_node, 1));
1907 else
1908 cond = gfc_omp_call_is_alloc (pointer);
1909 omp_tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
1910 omp_tmp = build_call_expr_loc (input_location, omp_tmp, 2, pointer,
1911 build_zero_cst (ptr_type_node));
1912 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1913 omp_tmp, tmp);
1915 gfc_add_expr_to_block (&non_null, tmp);
1916 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1917 0));
1918 if (flag_openmp_allocators && descr)
1919 gfc_add_modify (&non_null, gfc_conv_descriptor_version (descr),
1920 build_zero_cst (integer_type_node));
1922 if (status != NULL_TREE && !integer_zerop (status))
1924 /* We set STATUS to zero if it is present. */
1925 tree status_type = TREE_TYPE (TREE_TYPE (status));
1926 tree cond2;
1928 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1929 status,
1930 build_int_cst (TREE_TYPE (status), 0));
1931 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1932 fold_build1_loc (input_location, INDIRECT_REF,
1933 status_type, status),
1934 build_int_cst (status_type, 0));
1935 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1936 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1937 tmp, build_empty_stmt (input_location));
1938 gfc_add_expr_to_block (&non_null, tmp);
1941 else
1943 tree cond2, pstat = null_pointer_node;
1945 if (errmsg == NULL_TREE)
1947 gcc_assert (errlen == NULL_TREE);
1948 errmsg = null_pointer_node;
1949 errlen = build_zero_cst (integer_type_node);
1951 else
1953 gcc_assert (errlen != NULL_TREE);
1954 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1955 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1958 if (status != NULL_TREE && !integer_zerop (status))
1960 gcc_assert (status_type == integer_type_node);
1961 pstat = status;
1964 token = gfc_build_addr_expr (NULL_TREE, token);
1965 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
1966 tmp = build_call_expr_loc (input_location,
1967 gfor_fndecl_caf_deregister, 5,
1968 token, build_int_cst (integer_type_node,
1969 caf_dereg_type),
1970 pstat, errmsg, errlen);
1971 gfc_add_expr_to_block (&non_null, tmp);
1973 /* It guarantees memory consistency within the same segment */
1974 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1975 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1976 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1977 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1978 ASM_VOLATILE_P (tmp) = 1;
1979 gfc_add_expr_to_block (&non_null, tmp);
1981 if (status != NULL_TREE)
1983 tree stat = build_fold_indirect_ref_loc (input_location, status);
1984 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1985 void_type_node, pointer,
1986 build_int_cst (TREE_TYPE (pointer),
1987 0));
1989 TREE_USED (label_finish) = 1;
1990 tmp = build1_v (GOTO_EXPR, label_finish);
1991 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1992 stat, build_zero_cst (TREE_TYPE (stat)));
1993 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1994 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1995 tmp, nullify);
1996 gfc_add_expr_to_block (&non_null, tmp);
1998 else
1999 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
2000 0));
2003 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
2004 gfc_finish_block (&null),
2005 gfc_finish_block (&non_null));
2009 /* Generate code for deallocation of allocatable scalars (variables or
2010 components). Before the object itself is freed, any allocatable
2011 subcomponents are being deallocated. */
2013 tree
2014 gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
2015 bool can_fail, gfc_expr* expr,
2016 gfc_typespec ts, tree class_container,
2017 bool coarray)
2019 stmtblock_t null, non_null;
2020 tree cond, tmp, error;
2021 bool finalizable, comp_ref;
2022 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
2024 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
2025 && comp_ref)
2026 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
2028 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
2029 build_int_cst (TREE_TYPE (pointer), 0));
2031 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
2032 we emit a runtime error. */
2033 gfc_start_block (&null);
2034 if (!can_fail)
2036 tree varname;
2038 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
2040 varname = gfc_build_cstring_const (expr->symtree->name);
2041 varname = gfc_build_addr_expr (pchar_type_node, varname);
2043 error = gfc_trans_runtime_error (true, &expr->where,
2044 "Attempt to DEALLOCATE unallocated '%s'",
2045 varname);
2047 else
2048 error = build_empty_stmt (input_location);
2050 if (status != NULL_TREE && !integer_zerop (status))
2052 tree status_type = TREE_TYPE (TREE_TYPE (status));
2053 tree cond2;
2055 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2056 status, build_int_cst (TREE_TYPE (status), 0));
2057 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
2058 fold_build1_loc (input_location, INDIRECT_REF,
2059 status_type, status),
2060 build_int_cst (status_type, 1));
2061 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2062 cond2, tmp, error);
2064 gfc_add_expr_to_block (&null, error);
2066 /* When POINTER is not NULL, we free it. */
2067 gfc_start_block (&non_null);
2069 /* Free allocatable components. */
2070 finalizable = gfc_add_finalizer_call (&non_null, expr, class_container);
2071 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2073 int caf_mode = coarray
2074 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
2075 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
2076 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
2077 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
2078 : 0;
2079 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
2080 tmp = gfc_conv_descriptor_data_get (pointer);
2081 else
2082 tmp = build_fold_indirect_ref_loc (input_location, pointer);
2083 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
2084 gfc_add_expr_to_block (&non_null, tmp);
2087 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
2089 tmp = build_call_expr_loc (input_location,
2090 builtin_decl_explicit (BUILT_IN_FREE), 1,
2091 fold_convert (pvoid_type_node, pointer));
2092 if (flag_openmp_allocators)
2094 tree cond, omp_tmp;
2095 cond = gfc_omp_call_is_alloc (pointer);
2096 omp_tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
2097 omp_tmp = build_call_expr_loc (input_location, omp_tmp, 2, pointer,
2098 build_zero_cst (ptr_type_node));
2099 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
2100 omp_tmp, tmp);
2102 gfc_add_expr_to_block (&non_null, tmp);
2104 if (status != NULL_TREE && !integer_zerop (status))
2106 /* We set STATUS to zero if it is present. */
2107 tree status_type = TREE_TYPE (TREE_TYPE (status));
2108 tree cond2;
2110 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2111 status,
2112 build_int_cst (TREE_TYPE (status), 0));
2113 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
2114 fold_build1_loc (input_location, INDIRECT_REF,
2115 status_type, status),
2116 build_int_cst (status_type, 0));
2117 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2118 cond2, tmp, build_empty_stmt (input_location));
2119 gfc_add_expr_to_block (&non_null, tmp);
2122 else
2124 tree token;
2125 tree pstat = null_pointer_node;
2126 gfc_se se;
2128 gfc_init_se (&se, NULL);
2129 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
2130 gcc_assert (token != NULL_TREE);
2132 if (status != NULL_TREE && !integer_zerop (status))
2134 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
2135 pstat = status;
2138 tmp = build_call_expr_loc (input_location,
2139 gfor_fndecl_caf_deregister, 5,
2140 token, build_int_cst (integer_type_node,
2141 caf_dereg_type),
2142 pstat, null_pointer_node, integer_zero_node);
2143 gfc_add_expr_to_block (&non_null, tmp);
2145 /* It guarantees memory consistency within the same segment. */
2146 tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
2147 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
2148 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
2149 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
2150 ASM_VOLATILE_P (tmp) = 1;
2151 gfc_add_expr_to_block (&non_null, tmp);
2153 if (status != NULL_TREE)
2155 tree stat = build_fold_indirect_ref_loc (input_location, status);
2156 tree cond2;
2158 TREE_USED (label_finish) = 1;
2159 tmp = build1_v (GOTO_EXPR, label_finish);
2160 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2161 stat, build_zero_cst (TREE_TYPE (stat)));
2162 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2163 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
2164 tmp, build_empty_stmt (input_location));
2165 gfc_add_expr_to_block (&non_null, tmp);
2169 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
2170 gfc_finish_block (&null),
2171 gfc_finish_block (&non_null));
2174 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
2175 following pseudo-code:
2177 void *
2178 internal_realloc (void *mem, size_t size)
2180 res = realloc (mem, size);
2181 if (!res && size != 0)
2182 _gfortran_os_error ("Allocation would exceed memory limit");
2184 return res;
2185 } */
2186 tree
2187 gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
2189 tree res, nonzero, null_result, tmp;
2190 tree type = TREE_TYPE (mem);
2192 /* Only evaluate the size once. */
2193 size = save_expr (fold_convert (size_type_node, size));
2195 /* Create a variable to hold the result. */
2196 res = gfc_create_var (type, NULL);
2198 /* Call realloc and check the result. */
2199 tmp = build_call_expr_loc (input_location,
2200 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
2201 fold_convert (pvoid_type_node, mem), size);
2202 gfc_add_modify (block, res, fold_convert (type, tmp));
2203 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2204 res, build_int_cst (pvoid_type_node, 0));
2205 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
2206 build_int_cst (size_type_node, 0));
2207 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
2208 null_result, nonzero);
2209 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2210 null_result,
2211 trans_os_error_at (NULL,
2212 "Error reallocating to %lu bytes",
2213 fold_convert
2214 (long_unsigned_type_node, size)),
2215 build_empty_stmt (input_location));
2216 gfc_add_expr_to_block (block, tmp);
2218 return res;
2222 /* Add an expression to another one, either at the front or the back. */
2224 static void
2225 add_expr_to_chain (tree* chain, tree expr, bool front)
2227 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
2228 return;
2230 if (*chain)
2232 if (TREE_CODE (*chain) != STATEMENT_LIST)
2234 tree tmp;
2236 tmp = *chain;
2237 *chain = NULL_TREE;
2238 append_to_statement_list (tmp, chain);
2241 if (front)
2243 tree_stmt_iterator i;
2245 i = tsi_start (*chain);
2246 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
2248 else
2249 append_to_statement_list (expr, chain);
2251 else
2252 *chain = expr;
2256 /* Add a statement at the end of a block. */
2258 void
2259 gfc_add_expr_to_block (stmtblock_t * block, tree expr)
2261 gcc_assert (block);
2262 add_expr_to_chain (&block->head, expr, false);
2266 /* Add a statement at the beginning of a block. */
2268 void
2269 gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
2271 gcc_assert (block);
2272 add_expr_to_chain (&block->head, expr, true);
2276 /* Add a block the end of a block. */
2278 void
2279 gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
2281 gcc_assert (append);
2282 gcc_assert (!append->has_scope);
2284 gfc_add_expr_to_block (block, append->head);
2285 append->head = NULL_TREE;
2289 /* Save the current locus. The structure may not be complete, and should
2290 only be used with gfc_restore_backend_locus. */
2292 void
2293 gfc_save_backend_locus (locus * loc)
2295 loc->lb = XCNEW (gfc_linebuf);
2296 loc->lb->location = input_location;
2297 loc->lb->file = gfc_current_backend_file;
2301 /* Set the current locus. */
2303 void
2304 gfc_set_backend_locus (locus * loc)
2306 gfc_current_backend_file = loc->lb->file;
2307 input_location = gfc_get_location (loc);
2311 /* Restore the saved locus. Only used in conjunction with
2312 gfc_save_backend_locus, to free the memory when we are done. */
2314 void
2315 gfc_restore_backend_locus (locus * loc)
2317 /* This only restores the information captured by gfc_save_backend_locus,
2318 intentionally does not use gfc_get_location. */
2319 input_location = loc->lb->location;
2320 gfc_current_backend_file = loc->lb->file;
2321 free (loc->lb);
2325 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
2326 This static function is wrapped by gfc_trans_code_cond and
2327 gfc_trans_code. */
2329 static tree
2330 trans_code (gfc_code * code, tree cond)
2332 stmtblock_t block;
2333 tree res;
2335 if (!code)
2336 return build_empty_stmt (input_location);
2338 gfc_start_block (&block);
2340 /* Translate statements one by one into GENERIC trees until we reach
2341 the end of this gfc_code branch. */
2342 for (; code; code = code->next)
2344 if (code->here != 0)
2346 res = gfc_trans_label_here (code);
2347 gfc_add_expr_to_block (&block, res);
2350 gfc_current_locus = code->loc;
2351 gfc_set_backend_locus (&code->loc);
2353 switch (code->op)
2355 case EXEC_NOP:
2356 case EXEC_END_BLOCK:
2357 case EXEC_END_NESTED_BLOCK:
2358 case EXEC_END_PROCEDURE:
2359 res = NULL_TREE;
2360 break;
2362 case EXEC_ASSIGN:
2363 res = gfc_trans_assign (code);
2364 break;
2366 case EXEC_LABEL_ASSIGN:
2367 res = gfc_trans_label_assign (code);
2368 break;
2370 case EXEC_POINTER_ASSIGN:
2371 res = gfc_trans_pointer_assign (code);
2372 break;
2374 case EXEC_INIT_ASSIGN:
2375 if (code->expr1->ts.type == BT_CLASS)
2376 res = gfc_trans_class_init_assign (code);
2377 else
2378 res = gfc_trans_init_assign (code);
2379 break;
2381 case EXEC_CONTINUE:
2382 res = NULL_TREE;
2383 break;
2385 case EXEC_CRITICAL:
2386 res = gfc_trans_critical (code);
2387 break;
2389 case EXEC_CYCLE:
2390 res = gfc_trans_cycle (code);
2391 break;
2393 case EXEC_EXIT:
2394 res = gfc_trans_exit (code);
2395 break;
2397 case EXEC_GOTO:
2398 res = gfc_trans_goto (code);
2399 break;
2401 case EXEC_ENTRY:
2402 res = gfc_trans_entry (code);
2403 break;
2405 case EXEC_PAUSE:
2406 res = gfc_trans_pause (code);
2407 break;
2409 case EXEC_STOP:
2410 case EXEC_ERROR_STOP:
2411 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
2412 break;
2414 case EXEC_CALL:
2415 /* For MVBITS we've got the special exception that we need a
2416 dependency check, too. */
2418 bool is_mvbits = false;
2420 if (code->resolved_isym)
2422 res = gfc_conv_intrinsic_subroutine (code);
2423 if (res != NULL_TREE)
2424 break;
2427 if (code->resolved_isym
2428 && code->resolved_isym->id == GFC_ISYM_MVBITS)
2429 is_mvbits = true;
2431 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
2432 NULL_TREE, false);
2434 break;
2436 case EXEC_CALL_PPC:
2437 res = gfc_trans_call (code, false, NULL_TREE,
2438 NULL_TREE, false);
2439 break;
2441 case EXEC_ASSIGN_CALL:
2442 res = gfc_trans_call (code, true, NULL_TREE,
2443 NULL_TREE, false);
2444 break;
2446 case EXEC_RETURN:
2447 res = gfc_trans_return (code);
2448 break;
2450 case EXEC_IF:
2451 res = gfc_trans_if (code);
2452 break;
2454 case EXEC_ARITHMETIC_IF:
2455 res = gfc_trans_arithmetic_if (code);
2456 break;
2458 case EXEC_BLOCK:
2459 res = gfc_trans_block_construct (code);
2460 break;
2462 case EXEC_DO:
2463 res = gfc_trans_do (code, cond);
2464 break;
2466 case EXEC_DO_CONCURRENT:
2467 res = gfc_trans_do_concurrent (code);
2468 break;
2470 case EXEC_DO_WHILE:
2471 res = gfc_trans_do_while (code);
2472 break;
2474 case EXEC_SELECT:
2475 res = gfc_trans_select (code);
2476 break;
2478 case EXEC_SELECT_TYPE:
2479 res = gfc_trans_select_type (code);
2480 break;
2482 case EXEC_SELECT_RANK:
2483 res = gfc_trans_select_rank (code);
2484 break;
2486 case EXEC_FLUSH:
2487 res = gfc_trans_flush (code);
2488 break;
2490 case EXEC_SYNC_ALL:
2491 case EXEC_SYNC_IMAGES:
2492 case EXEC_SYNC_MEMORY:
2493 res = gfc_trans_sync (code, code->op);
2494 break;
2496 case EXEC_LOCK:
2497 case EXEC_UNLOCK:
2498 res = gfc_trans_lock_unlock (code, code->op);
2499 break;
2501 case EXEC_EVENT_POST:
2502 case EXEC_EVENT_WAIT:
2503 res = gfc_trans_event_post_wait (code, code->op);
2504 break;
2506 case EXEC_FAIL_IMAGE:
2507 res = gfc_trans_fail_image (code);
2508 break;
2510 case EXEC_FORALL:
2511 res = gfc_trans_forall (code);
2512 break;
2514 case EXEC_FORM_TEAM:
2515 res = gfc_trans_form_team (code);
2516 break;
2518 case EXEC_CHANGE_TEAM:
2519 res = gfc_trans_change_team (code);
2520 break;
2522 case EXEC_END_TEAM:
2523 res = gfc_trans_end_team (code);
2524 break;
2526 case EXEC_SYNC_TEAM:
2527 res = gfc_trans_sync_team (code);
2528 break;
2530 case EXEC_WHERE:
2531 res = gfc_trans_where (code);
2532 break;
2534 case EXEC_ALLOCATE:
2535 res = gfc_trans_allocate (code, NULL);
2536 break;
2538 case EXEC_DEALLOCATE:
2539 res = gfc_trans_deallocate (code);
2540 break;
2542 case EXEC_OPEN:
2543 res = gfc_trans_open (code);
2544 break;
2546 case EXEC_CLOSE:
2547 res = gfc_trans_close (code);
2548 break;
2550 case EXEC_READ:
2551 res = gfc_trans_read (code);
2552 break;
2554 case EXEC_WRITE:
2555 res = gfc_trans_write (code);
2556 break;
2558 case EXEC_IOLENGTH:
2559 res = gfc_trans_iolength (code);
2560 break;
2562 case EXEC_BACKSPACE:
2563 res = gfc_trans_backspace (code);
2564 break;
2566 case EXEC_ENDFILE:
2567 res = gfc_trans_endfile (code);
2568 break;
2570 case EXEC_INQUIRE:
2571 res = gfc_trans_inquire (code);
2572 break;
2574 case EXEC_WAIT:
2575 res = gfc_trans_wait (code);
2576 break;
2578 case EXEC_REWIND:
2579 res = gfc_trans_rewind (code);
2580 break;
2582 case EXEC_TRANSFER:
2583 res = gfc_trans_transfer (code);
2584 break;
2586 case EXEC_DT_END:
2587 res = gfc_trans_dt_end (code);
2588 break;
2590 case EXEC_OMP_ALLOCATE:
2591 case EXEC_OMP_ALLOCATORS:
2592 case EXEC_OMP_ASSUME:
2593 case EXEC_OMP_ATOMIC:
2594 case EXEC_OMP_BARRIER:
2595 case EXEC_OMP_CANCEL:
2596 case EXEC_OMP_CANCELLATION_POINT:
2597 case EXEC_OMP_CRITICAL:
2598 case EXEC_OMP_DEPOBJ:
2599 case EXEC_OMP_DISTRIBUTE:
2600 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2601 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2602 case EXEC_OMP_DISTRIBUTE_SIMD:
2603 case EXEC_OMP_DO:
2604 case EXEC_OMP_DO_SIMD:
2605 case EXEC_OMP_LOOP:
2606 case EXEC_OMP_ERROR:
2607 case EXEC_OMP_FLUSH:
2608 case EXEC_OMP_MASKED:
2609 case EXEC_OMP_MASKED_TASKLOOP:
2610 case EXEC_OMP_MASKED_TASKLOOP_SIMD:
2611 case EXEC_OMP_MASTER:
2612 case EXEC_OMP_MASTER_TASKLOOP:
2613 case EXEC_OMP_MASTER_TASKLOOP_SIMD:
2614 case EXEC_OMP_ORDERED:
2615 case EXEC_OMP_PARALLEL:
2616 case EXEC_OMP_PARALLEL_DO:
2617 case EXEC_OMP_PARALLEL_DO_SIMD:
2618 case EXEC_OMP_PARALLEL_LOOP:
2619 case EXEC_OMP_PARALLEL_MASKED:
2620 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
2621 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
2622 case EXEC_OMP_PARALLEL_MASTER:
2623 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
2624 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
2625 case EXEC_OMP_PARALLEL_SECTIONS:
2626 case EXEC_OMP_PARALLEL_WORKSHARE:
2627 case EXEC_OMP_SCOPE:
2628 case EXEC_OMP_SECTIONS:
2629 case EXEC_OMP_SIMD:
2630 case EXEC_OMP_SINGLE:
2631 case EXEC_OMP_TARGET:
2632 case EXEC_OMP_TARGET_DATA:
2633 case EXEC_OMP_TARGET_ENTER_DATA:
2634 case EXEC_OMP_TARGET_EXIT_DATA:
2635 case EXEC_OMP_TARGET_PARALLEL:
2636 case EXEC_OMP_TARGET_PARALLEL_DO:
2637 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2638 case EXEC_OMP_TARGET_PARALLEL_LOOP:
2639 case EXEC_OMP_TARGET_SIMD:
2640 case EXEC_OMP_TARGET_TEAMS:
2641 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2642 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2643 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2644 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2645 case EXEC_OMP_TARGET_TEAMS_LOOP:
2646 case EXEC_OMP_TARGET_UPDATE:
2647 case EXEC_OMP_TASK:
2648 case EXEC_OMP_TASKGROUP:
2649 case EXEC_OMP_TASKLOOP:
2650 case EXEC_OMP_TASKLOOP_SIMD:
2651 case EXEC_OMP_TASKWAIT:
2652 case EXEC_OMP_TASKYIELD:
2653 case EXEC_OMP_TEAMS:
2654 case EXEC_OMP_TEAMS_DISTRIBUTE:
2655 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2656 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2657 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
2658 case EXEC_OMP_TEAMS_LOOP:
2659 case EXEC_OMP_WORKSHARE:
2660 res = gfc_trans_omp_directive (code);
2661 break;
2663 case EXEC_OACC_CACHE:
2664 case EXEC_OACC_WAIT:
2665 case EXEC_OACC_UPDATE:
2666 case EXEC_OACC_LOOP:
2667 case EXEC_OACC_HOST_DATA:
2668 case EXEC_OACC_DATA:
2669 case EXEC_OACC_KERNELS:
2670 case EXEC_OACC_KERNELS_LOOP:
2671 case EXEC_OACC_PARALLEL:
2672 case EXEC_OACC_PARALLEL_LOOP:
2673 case EXEC_OACC_SERIAL:
2674 case EXEC_OACC_SERIAL_LOOP:
2675 case EXEC_OACC_ENTER_DATA:
2676 case EXEC_OACC_EXIT_DATA:
2677 case EXEC_OACC_ATOMIC:
2678 case EXEC_OACC_DECLARE:
2679 res = gfc_trans_oacc_directive (code);
2680 break;
2682 default:
2683 gfc_internal_error ("gfc_trans_code(): Bad statement code");
2686 gfc_set_backend_locus (&code->loc);
2688 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2690 if (TREE_CODE (res) != STATEMENT_LIST)
2691 SET_EXPR_LOCATION (res, input_location);
2693 /* Add the new statement to the block. */
2694 gfc_add_expr_to_block (&block, res);
2698 /* Return the finished block. */
2699 return gfc_finish_block (&block);
2703 /* Translate an executable statement with condition, cond. The condition is
2704 used by gfc_trans_do to test for IO result conditions inside implied
2705 DO loops of READ and WRITE statements. See build_dt in trans-io.cc. */
2707 tree
2708 gfc_trans_code_cond (gfc_code * code, tree cond)
2710 return trans_code (code, cond);
2713 /* Translate an executable statement without condition. */
2715 tree
2716 gfc_trans_code (gfc_code * code)
2718 return trans_code (code, NULL_TREE);
2722 /* This function is called after a complete program unit has been parsed
2723 and resolved. */
2725 void
2726 gfc_generate_code (gfc_namespace * ns)
2728 ompws_flags = 0;
2729 if (ns->is_block_data)
2731 gfc_generate_block_data (ns);
2732 return;
2735 gfc_generate_function_code (ns);
2739 /* This function is called after a complete module has been parsed
2740 and resolved. */
2742 void
2743 gfc_generate_module_code (gfc_namespace * ns)
2745 gfc_namespace *n;
2746 struct module_htab_entry *entry;
2748 gcc_assert (ns->proc_name->backend_decl == NULL);
2749 ns->proc_name->backend_decl
2750 = build_decl (gfc_get_location (&ns->proc_name->declared_at),
2751 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
2752 void_type_node);
2753 entry = gfc_find_module (ns->proc_name->name);
2754 if (entry->namespace_decl)
2755 /* Buggy sourcecode, using a module before defining it? */
2756 entry->decls->empty ();
2757 entry->namespace_decl = ns->proc_name->backend_decl;
2759 gfc_generate_module_vars (ns);
2761 /* We need to generate all module function prototypes first, to allow
2762 sibling calls. */
2763 for (n = ns->contained; n; n = n->sibling)
2765 gfc_entry_list *el;
2767 if (!n->proc_name)
2768 continue;
2770 gfc_create_function_decl (n, false);
2771 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2772 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2773 for (el = ns->entries; el; el = el->next)
2775 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2776 gfc_module_add_decl (entry, el->sym->backend_decl);
2780 for (n = ns->contained; n; n = n->sibling)
2782 if (!n->proc_name)
2783 continue;
2785 gfc_generate_function_code (n);
2790 /* Initialize an init/cleanup block with existing code. */
2792 void
2793 gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2795 gcc_assert (block);
2797 block->init = NULL_TREE;
2798 block->code = code;
2799 block->cleanup = NULL_TREE;
2803 /* Add a new pair of initializers/clean-up code. */
2805 void
2806 gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2808 gcc_assert (block);
2810 /* The new pair of init/cleanup should be "wrapped around" the existing
2811 block of code, thus the initialization is added to the front and the
2812 cleanup to the back. */
2813 add_expr_to_chain (&block->init, init, true);
2814 add_expr_to_chain (&block->cleanup, cleanup, false);
2818 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2820 tree
2821 gfc_finish_wrapped_block (gfc_wrapped_block* block)
2823 tree result;
2825 gcc_assert (block);
2827 /* Build the final expression. For this, just add init and body together,
2828 and put clean-up with that into a TRY_FINALLY_EXPR. */
2829 result = block->init;
2830 add_expr_to_chain (&result, block->code, false);
2831 if (block->cleanup)
2832 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2833 result, block->cleanup);
2835 /* Clear the block. */
2836 block->init = NULL_TREE;
2837 block->code = NULL_TREE;
2838 block->cleanup = NULL_TREE;
2840 return result;
2844 /* Helper function for marking a boolean expression tree as unlikely. */
2846 tree
2847 gfc_unlikely (tree cond, enum br_predictor predictor)
2849 tree tmp;
2851 if (optimize)
2853 cond = fold_convert (long_integer_type_node, cond);
2854 tmp = build_zero_cst (long_integer_type_node);
2855 cond = build_call_expr_loc (input_location,
2856 builtin_decl_explicit (BUILT_IN_EXPECT),
2857 3, cond, tmp,
2858 build_int_cst (integer_type_node,
2859 predictor));
2861 return cond;
2865 /* Helper function for marking a boolean expression tree as likely. */
2867 tree
2868 gfc_likely (tree cond, enum br_predictor predictor)
2870 tree tmp;
2872 if (optimize)
2874 cond = fold_convert (long_integer_type_node, cond);
2875 tmp = build_one_cst (long_integer_type_node);
2876 cond = build_call_expr_loc (input_location,
2877 builtin_decl_explicit (BUILT_IN_EXPECT),
2878 3, cond, tmp,
2879 build_int_cst (integer_type_node,
2880 predictor));
2882 return cond;
2886 /* Get the string length for a deferred character length component. */
2888 bool
2889 gfc_deferred_strlen (gfc_component *c, tree *decl)
2891 char name[GFC_MAX_SYMBOL_LEN+9];
2892 gfc_component *strlen;
2893 if (!(c->ts.type == BT_CHARACTER
2894 && (c->ts.deferred || c->attr.pdt_string)))
2895 return false;
2896 sprintf (name, "_%s_length", c->name);
2897 for (strlen = c; strlen; strlen = strlen->next)
2898 if (strcmp (strlen->name, name) == 0)
2899 break;
2900 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2901 return strlen != NULL;