1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2021 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
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
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/>. */
23 #include "coretypes.h"
27 #include "gimple-expr.h" /* For create_tmp_var_raw. */
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.c's gfc_format_decoder. */
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. */
65 gfc_advance_chain (tree t
, int n
)
69 gcc_assert (t
!= NULL_TREE
);
77 #define MAX_PREFIX_LEN 20
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];
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;
117 /* Creates a variable declaration with a given TYPE. */
120 gfc_create_var_np (tree type
, const char *prefix
)
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. */
131 suppress_warning (t
);
137 /* Like above, but also adds it to the current scope. */
140 gfc_create_var (tree type
, const char *prefix
)
144 tmp
= gfc_create_var_np (type
, prefix
);
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. */
157 gfc_evaluate_now_loc (location_t loc
, tree expr
, stmtblock_t
* pblock
)
161 if (CONSTANT_CLASS_P (expr
))
164 var
= gfc_create_var (TREE_TYPE (expr
), NULL
);
165 gfc_add_modify_loc (loc
, pblock
, var
, expr
);
172 gfc_evaluate_now (tree expr
, stmtblock_t
* pblock
)
174 return gfc_evaluate_now_loc (input_location
, expr
, pblock
);
177 /* Like gfc_evaluate_now, but add the created variable to the
181 gfc_evaluate_now_function_scope (tree expr
, stmtblock_t
* pblock
)
184 var
= gfc_create_var_np (TREE_TYPE (expr
), NULL
);
185 gfc_add_decl_to_function (var
);
186 gfc_add_modify (pblock
, var
, expr
);
191 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
192 A MODIFY_EXPR is an assignment:
196 gfc_add_modify_loc (location_t loc
, stmtblock_t
* pblock
, tree lhs
, tree rhs
)
201 t1
= TREE_TYPE (rhs
);
202 t2
= TREE_TYPE (lhs
);
203 /* Make sure that the types of the rhs and the lhs are compatible
204 for scalar assignments. We should probably have something
205 similar for aggregates, but right now removing that check just
206 breaks everything. */
207 gcc_checking_assert (TYPE_MAIN_VARIANT (t1
) == TYPE_MAIN_VARIANT (t2
)
208 || AGGREGATE_TYPE_P (TREE_TYPE (lhs
)));
210 tmp
= fold_build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
,
212 gfc_add_expr_to_block (pblock
, tmp
);
217 gfc_add_modify (stmtblock_t
* pblock
, tree lhs
, tree rhs
)
219 gfc_add_modify_loc (input_location
, pblock
, lhs
, rhs
);
223 /* Create a new scope/binding level and initialize a block. Care must be
224 taken when translating expressions as any temporaries will be placed in
225 the innermost scope. */
228 gfc_start_block (stmtblock_t
* block
)
230 /* Start a new binding level. */
232 block
->has_scope
= 1;
234 /* The block is empty. */
235 block
->head
= NULL_TREE
;
239 /* Initialize a block without creating a new scope. */
242 gfc_init_block (stmtblock_t
* block
)
244 block
->head
= NULL_TREE
;
245 block
->has_scope
= 0;
249 /* Sometimes we create a scope but it turns out that we don't actually
250 need it. This function merges the scope of BLOCK with its parent.
251 Only variable decls will be merged, you still need to add the code. */
254 gfc_merge_block_scope (stmtblock_t
* block
)
259 gcc_assert (block
->has_scope
);
260 block
->has_scope
= 0;
262 /* Remember the decls in this scope. */
266 /* Add them to the parent scope. */
267 while (decl
!= NULL_TREE
)
269 next
= DECL_CHAIN (decl
);
270 DECL_CHAIN (decl
) = NULL_TREE
;
278 /* Finish a scope containing a block of statements. */
281 gfc_finish_block (stmtblock_t
* stmtblock
)
287 expr
= stmtblock
->head
;
289 expr
= build_empty_stmt (input_location
);
291 stmtblock
->head
= NULL_TREE
;
293 if (stmtblock
->has_scope
)
299 block
= poplevel (1, 0);
300 expr
= build3_v (BIND_EXPR
, decl
, expr
, block
);
310 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
311 natural type is used. */
314 gfc_build_addr_expr (tree type
, tree t
)
316 tree base_type
= TREE_TYPE (t
);
319 if (type
&& POINTER_TYPE_P (type
)
320 && TREE_CODE (base_type
) == ARRAY_TYPE
321 && TYPE_MAIN_VARIANT (TREE_TYPE (type
))
322 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type
)))
324 tree min_val
= size_zero_node
;
325 tree type_domain
= TYPE_DOMAIN (base_type
);
326 if (type_domain
&& TYPE_MIN_VALUE (type_domain
))
327 min_val
= TYPE_MIN_VALUE (type_domain
);
328 t
= fold (build4_loc (input_location
, ARRAY_REF
, TREE_TYPE (type
),
329 t
, min_val
, NULL_TREE
, NULL_TREE
));
333 natural_type
= build_pointer_type (base_type
);
335 if (TREE_CODE (t
) == INDIRECT_REF
)
339 t
= TREE_OPERAND (t
, 0);
340 natural_type
= TREE_TYPE (t
);
344 tree base
= get_base_address (t
);
345 if (base
&& DECL_P (base
))
346 TREE_ADDRESSABLE (base
) = 1;
347 t
= fold_build1_loc (input_location
, ADDR_EXPR
, natural_type
, t
);
350 if (type
&& natural_type
!= type
)
351 t
= convert (type
, t
);
358 get_array_span (tree type
, tree decl
)
362 /* Component references are guaranteed to have a reliable value for
363 'span'. Likewise indirect references since they emerge from the
364 conversion of a CFI descriptor or the hidden dummy descriptor. */
365 if (TREE_CODE (decl
) == COMPONENT_REF
366 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
)))
367 return gfc_conv_descriptor_span_get (decl
);
368 else if (TREE_CODE (decl
) == INDIRECT_REF
369 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
)))
370 return gfc_conv_descriptor_span_get (decl
);
372 /* Return the span for deferred character length array references. */
373 if (type
&& TREE_CODE (type
) == ARRAY_TYPE
&& TYPE_STRING_FLAG (type
))
375 if (TREE_CODE (decl
) == PARM_DECL
)
376 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
377 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
)))
378 span
= gfc_conv_descriptor_span_get (decl
);
380 span
= gfc_get_character_len_in_bytes (type
);
381 span
= (span
&& !integer_zerop (span
))
382 ? (fold_convert (gfc_array_index_type
, span
)) : (NULL_TREE
);
384 /* Likewise for class array or pointer array references. */
385 else if (TREE_CODE (decl
) == FIELD_DECL
386 || VAR_OR_FUNCTION_DECL_P (decl
)
387 || TREE_CODE (decl
) == PARM_DECL
)
389 if (GFC_DECL_CLASS (decl
))
391 /* When a temporary is in place for the class array, then the
392 original class' declaration is stored in the saved
394 if (DECL_LANG_SPECIFIC (decl
) && GFC_DECL_SAVED_DESCRIPTOR (decl
))
395 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
398 /* Allow for dummy arguments and other good things. */
399 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
400 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
402 /* Check if '_data' is an array descriptor. If it is not,
403 the array must be one of the components of the class
404 object, so return a null span. */
405 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
406 gfc_class_data_get (decl
))))
409 span
= gfc_class_vtab_size_get (decl
);
410 /* For unlimited polymorphic entities then _len component needs
411 to be multiplied with the size. */
412 span
= gfc_resize_class_size_with_len (NULL
, decl
, span
);
414 else if (GFC_DECL_PTR_ARRAY_P (decl
))
416 if (TREE_CODE (decl
) == PARM_DECL
)
417 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
418 span
= gfc_conv_descriptor_span_get (decl
);
431 gfc_build_spanned_array_ref (tree base
, tree offset
, tree span
)
435 type
= TREE_TYPE (TREE_TYPE (base
));
436 offset
= fold_build2_loc (input_location
, MULT_EXPR
,
437 gfc_array_index_type
,
439 tmp
= gfc_build_addr_expr (pvoid_type_node
, base
);
440 tmp
= fold_build_pointer_plus_loc (input_location
, tmp
, offset
);
441 tmp
= fold_convert (build_pointer_type (type
), tmp
);
442 if ((TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != ARRAY_TYPE
)
443 || !TYPE_STRING_FLAG (type
))
444 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
449 /* Build an ARRAY_REF with its natural type. */
452 gfc_build_array_ref (tree base
, tree offset
, tree decl
, tree vptr
)
454 tree type
= TREE_TYPE (base
);
455 tree span
= NULL_TREE
;
457 if (GFC_ARRAY_TYPE_P (type
) && GFC_TYPE_ARRAY_RANK (type
) == 0)
459 gcc_assert (GFC_TYPE_ARRAY_CORANK (type
) > 0);
461 return fold_convert (TYPE_MAIN_VARIANT (type
), base
);
464 /* Scalar coarray, there is nothing to do. */
465 if (TREE_CODE (type
) != ARRAY_TYPE
)
467 gcc_assert (decl
== NULL_TREE
);
468 gcc_assert (integer_zerop (offset
));
472 type
= TREE_TYPE (type
);
475 TREE_ADDRESSABLE (base
) = 1;
477 /* Strip NON_LVALUE_EXPR nodes. */
478 STRIP_TYPE_NOPS (offset
);
480 /* If decl or vptr are non-null, pointer arithmetic for the array reference
481 is likely. Generate the 'span' for the array reference. */
484 span
= gfc_vptr_size_get (vptr
);
486 /* Check if this is an unlimited polymorphic object carrying a character
487 payload. In this case, the 'len' field is non-zero. */
488 if (decl
&& GFC_CLASS_TYPE_P (TREE_TYPE (decl
)))
489 span
= gfc_resize_class_size_with_len (NULL
, decl
, span
);
492 span
= get_array_span (type
, decl
);
494 /* If a non-null span has been generated reference the element with
495 pointer arithmetic. */
496 if (span
!= NULL_TREE
)
497 return gfc_build_spanned_array_ref (base
, offset
, span
);
498 /* Otherwise use a straightforward array reference. */
500 return build4_loc (input_location
, ARRAY_REF
, type
, base
, offset
,
501 NULL_TREE
, NULL_TREE
);
505 /* Generate a call to print a runtime error possibly including multiple
506 arguments and a locus. */
509 trans_runtime_error_vararg (tree errorfunc
, locus
* where
, const char* msgid
,
522 /* Compute the number of extra arguments from the format string. */
523 for (p
= msgid
, nargs
= 0; *p
; p
++)
531 /* The code to generate the error. */
532 gfc_start_block (&block
);
536 line
= LOCATION_LINE (where
->lb
->location
);
537 message
= xasprintf ("At line %d of file %s", line
,
538 where
->lb
->file
->filename
);
541 message
= xasprintf ("In file '%s', around line %d",
542 gfc_source_file
, LOCATION_LINE (input_location
) + 1);
544 arg
= gfc_build_addr_expr (pchar_type_node
,
545 gfc_build_localized_cstring_const (message
));
548 message
= xasprintf ("%s", _(msgid
));
549 arg2
= gfc_build_addr_expr (pchar_type_node
,
550 gfc_build_localized_cstring_const (message
));
553 /* Build the argument array. */
554 argarray
= XALLOCAVEC (tree
, nargs
+ 2);
557 for (i
= 0; i
< nargs
; i
++)
558 argarray
[2 + i
] = va_arg (ap
, tree
);
560 /* Build the function call to runtime_(warning,error)_at; because of the
561 variable number of arguments, we can't use build_call_expr_loc dinput_location,
563 fntype
= TREE_TYPE (errorfunc
);
565 loc
= where
? gfc_get_location (where
) : input_location
;
566 tmp
= fold_build_call_array_loc (loc
, TREE_TYPE (fntype
),
567 fold_build1_loc (loc
, ADDR_EXPR
,
568 build_pointer_type (fntype
),
570 nargs
+ 2, argarray
);
571 gfc_add_expr_to_block (&block
, tmp
);
573 return gfc_finish_block (&block
);
578 gfc_trans_runtime_error (bool error
, locus
* where
, const char* msgid
, ...)
583 va_start (ap
, msgid
);
584 result
= trans_runtime_error_vararg (error
585 ? gfor_fndecl_runtime_error_at
586 : gfor_fndecl_runtime_warning_at
,
593 /* Generate a runtime error if COND is true. */
596 gfc_trans_runtime_check (bool error
, bool once
, tree cond
, stmtblock_t
* pblock
,
597 locus
* where
, const char * msgid
, ...)
605 if (integer_zerop (cond
))
610 tmpvar
= gfc_create_var (boolean_type_node
, "print_warning");
611 TREE_STATIC (tmpvar
) = 1;
612 DECL_INITIAL (tmpvar
) = boolean_true_node
;
613 gfc_add_expr_to_block (pblock
, tmpvar
);
616 gfc_start_block (&block
);
618 /* For error, runtime_error_at already implies PRED_NORETURN. */
620 gfc_add_expr_to_block (&block
, build_predict_expr (PRED_FORTRAN_WARN_ONCE
,
623 /* The code to generate the error. */
624 va_start (ap
, msgid
);
625 gfc_add_expr_to_block (&block
,
626 trans_runtime_error_vararg
627 (error
? gfor_fndecl_runtime_error_at
628 : gfor_fndecl_runtime_warning_at
,
633 gfc_add_modify (&block
, tmpvar
, boolean_false_node
);
635 body
= gfc_finish_block (&block
);
637 if (integer_onep (cond
))
639 gfc_add_expr_to_block (pblock
, body
);
644 cond
= fold_build2_loc (gfc_get_location (where
), TRUTH_AND_EXPR
,
645 boolean_type_node
, tmpvar
,
646 fold_convert (boolean_type_node
, cond
));
648 tmp
= fold_build3_loc (gfc_get_location (where
), COND_EXPR
, void_type_node
,
650 build_empty_stmt (gfc_get_location (where
)));
651 gfc_add_expr_to_block (pblock
, tmp
);
657 trans_os_error_at (locus
* where
, const char* msgid
, ...)
662 va_start (ap
, msgid
);
663 result
= trans_runtime_error_vararg (gfor_fndecl_os_error_at
,
671 /* Call malloc to allocate size bytes of memory, with special conditions:
672 + if size == 0, return a malloced area of size 1,
673 + if malloc returns NULL, issue a runtime error. */
675 gfc_call_malloc (stmtblock_t
* block
, tree type
, tree size
)
677 tree tmp
, malloc_result
, null_result
, res
, malloc_tree
;
680 /* Create a variable to hold the result. */
681 res
= gfc_create_var (prvoid_type_node
, NULL
);
684 gfc_start_block (&block2
);
686 if (size
== NULL_TREE
)
687 size
= build_int_cst (size_type_node
, 1);
689 size
= fold_convert (size_type_node
, size
);
690 size
= fold_build2_loc (input_location
, MAX_EXPR
, size_type_node
, size
,
691 build_int_cst (size_type_node
, 1));
693 malloc_tree
= builtin_decl_explicit (BUILT_IN_MALLOC
);
694 gfc_add_modify (&block2
, res
,
695 fold_convert (prvoid_type_node
,
696 build_call_expr_loc (input_location
,
697 malloc_tree
, 1, size
)));
699 /* Optionally check whether malloc was successful. */
700 if (gfc_option
.rtcheck
& GFC_RTCHECK_MEM
)
702 null_result
= fold_build2_loc (input_location
, EQ_EXPR
,
703 logical_type_node
, res
,
704 build_int_cst (pvoid_type_node
, 0));
705 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
707 trans_os_error_at (NULL
,
708 "Error allocating %lu bytes",
710 (long_unsigned_type_node
,
712 build_empty_stmt (input_location
));
713 gfc_add_expr_to_block (&block2
, tmp
);
716 malloc_result
= gfc_finish_block (&block2
);
717 gfc_add_expr_to_block (block
, malloc_result
);
720 res
= fold_convert (type
, res
);
725 /* Allocate memory, using an optional status argument.
727 This function follows the following pseudo-code:
730 allocate (size_t size, integer_type stat)
737 newmem = malloc (MAX (size, 1));
741 *stat = LIBERROR_ALLOCATION;
743 runtime_error ("Allocation would exceed memory limit");
748 gfc_allocate_using_malloc (stmtblock_t
* block
, tree pointer
,
749 tree size
, tree status
)
751 tree tmp
, error_cond
;
752 stmtblock_t on_error
;
753 tree status_type
= status
? TREE_TYPE (status
) : NULL_TREE
;
755 /* If successful and stat= is given, set status to 0. */
756 if (status
!= NULL_TREE
)
757 gfc_add_expr_to_block (block
,
758 fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
759 status
, build_int_cst (status_type
, 0)));
761 /* The allocation itself. */
762 size
= fold_convert (size_type_node
, size
);
763 gfc_add_modify (block
, pointer
,
764 fold_convert (TREE_TYPE (pointer
),
765 build_call_expr_loc (input_location
,
766 builtin_decl_explicit (BUILT_IN_MALLOC
), 1,
767 fold_build2_loc (input_location
,
768 MAX_EXPR
, size_type_node
, size
,
769 build_int_cst (size_type_node
, 1)))));
771 /* What to do in case of error. */
772 gfc_start_block (&on_error
);
773 if (status
!= NULL_TREE
)
775 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
, status
,
776 build_int_cst (status_type
, LIBERROR_ALLOCATION
));
777 gfc_add_expr_to_block (&on_error
, tmp
);
781 /* Here, os_error_at already implies PRED_NORETURN. */
782 tree lusize
= fold_convert (long_unsigned_type_node
, size
);
783 tmp
= trans_os_error_at (NULL
, "Error allocating %lu bytes", lusize
);
784 gfc_add_expr_to_block (&on_error
, tmp
);
787 error_cond
= fold_build2_loc (input_location
, EQ_EXPR
,
788 logical_type_node
, pointer
,
789 build_int_cst (prvoid_type_node
, 0));
790 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
791 gfc_unlikely (error_cond
, PRED_FORTRAN_FAIL_ALLOC
),
792 gfc_finish_block (&on_error
),
793 build_empty_stmt (input_location
));
795 gfc_add_expr_to_block (block
, tmp
);
799 /* Allocate memory, using an optional status argument.
801 This function follows the following pseudo-code:
804 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
808 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
812 gfc_allocate_using_caf_lib (stmtblock_t
* block
, tree pointer
, tree size
,
813 tree token
, tree status
, tree errmsg
, tree errlen
,
814 gfc_coarray_regtype alloc_type
)
818 gcc_assert (token
!= NULL_TREE
);
820 /* The allocation itself. */
821 if (status
== NULL_TREE
)
822 pstat
= null_pointer_node
;
824 pstat
= gfc_build_addr_expr (NULL_TREE
, status
);
826 if (errmsg
== NULL_TREE
)
828 gcc_assert(errlen
== NULL_TREE
);
829 errmsg
= null_pointer_node
;
830 errlen
= build_int_cst (integer_type_node
, 0);
833 size
= fold_convert (size_type_node
, size
);
834 tmp
= build_call_expr_loc (input_location
,
835 gfor_fndecl_caf_register
, 7,
836 fold_build2_loc (input_location
,
837 MAX_EXPR
, size_type_node
, size
, size_one_node
),
838 build_int_cst (integer_type_node
, alloc_type
),
839 token
, gfc_build_addr_expr (pvoid_type_node
, pointer
),
840 pstat
, errmsg
, errlen
);
842 gfc_add_expr_to_block (block
, tmp
);
844 /* It guarantees memory consistency within the same segment */
845 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory"),
846 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
847 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
848 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
849 ASM_VOLATILE_P (tmp
) = 1;
850 gfc_add_expr_to_block (block
, tmp
);
854 /* Generate code for an ALLOCATE statement when the argument is an
855 allocatable variable. If the variable is currently allocated, it is an
856 error to allocate it again.
858 This function follows the following pseudo-code:
861 allocate_allocatable (void *mem, size_t size, integer_type stat)
864 return allocate (size, stat);
868 stat = LIBERROR_ALLOCATION;
870 runtime_error ("Attempting to allocate already allocated variable");
874 expr must be set to the original expression being allocated for its locus
875 and variable name in case a runtime error has to be printed. */
877 gfc_allocate_allocatable (stmtblock_t
* block
, tree mem
, tree size
,
878 tree token
, tree status
, tree errmsg
, tree errlen
,
879 tree label_finish
, gfc_expr
* expr
, int corank
)
881 stmtblock_t alloc_block
;
882 tree tmp
, null_mem
, alloc
, error
;
883 tree type
= TREE_TYPE (mem
);
884 symbol_attribute caf_attr
;
885 bool need_assign
= false, refs_comp
= false;
886 gfc_coarray_regtype caf_alloc_type
= GFC_CAF_COARRAY_ALLOC
;
888 size
= fold_convert (size_type_node
, size
);
889 null_mem
= gfc_unlikely (fold_build2_loc (input_location
, NE_EXPR
,
890 logical_type_node
, mem
,
891 build_int_cst (type
, 0)),
892 PRED_FORTRAN_REALLOC
);
894 /* If mem is NULL, we call gfc_allocate_using_malloc or
895 gfc_allocate_using_lib. */
896 gfc_start_block (&alloc_block
);
898 if (flag_coarray
== GFC_FCOARRAY_LIB
)
899 caf_attr
= gfc_caf_attr (expr
, true, &refs_comp
);
901 if (flag_coarray
== GFC_FCOARRAY_LIB
902 && (corank
> 0 || caf_attr
.codimension
))
904 tree cond
, sub_caf_tree
;
906 bool compute_special_caf_types_size
= false;
908 if (expr
->ts
.type
== BT_DERIVED
909 && expr
->ts
.u
.derived
->from_intmod
== INTMOD_ISO_FORTRAN_ENV
910 && expr
->ts
.u
.derived
->intmod_sym_id
== ISOFORTRAN_LOCK_TYPE
)
912 compute_special_caf_types_size
= true;
913 caf_alloc_type
= GFC_CAF_LOCK_ALLOC
;
915 else if (expr
->ts
.type
== BT_DERIVED
916 && expr
->ts
.u
.derived
->from_intmod
== INTMOD_ISO_FORTRAN_ENV
917 && expr
->ts
.u
.derived
->intmod_sym_id
== ISOFORTRAN_EVENT_TYPE
)
919 compute_special_caf_types_size
= true;
920 caf_alloc_type
= GFC_CAF_EVENT_ALLOC
;
922 else if (!caf_attr
.coarray_comp
&& refs_comp
)
923 /* Only allocatable components in a derived type coarray can be
925 caf_alloc_type
= GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY
;
927 gfc_init_se (&se
, NULL
);
928 sub_caf_tree
= gfc_get_ultimate_alloc_ptr_comps_caf_token (&se
, expr
);
929 if (sub_caf_tree
== NULL_TREE
)
930 sub_caf_tree
= token
;
932 /* When mem is an array ref, then strip the .data-ref. */
933 if (TREE_CODE (mem
) == COMPONENT_REF
934 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem
))))
935 tmp
= TREE_OPERAND (mem
, 0);
939 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp
))
940 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp
))->corank
== 0)
941 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp
)))
943 symbol_attribute attr
;
945 gfc_clear_attr (&attr
);
946 tmp
= gfc_conv_scalar_to_descriptor (&se
, mem
, attr
);
949 gfc_add_block_to_block (&alloc_block
, &se
.pre
);
951 /* In the front end, we represent the lock variable as pointer. However,
952 the FE only passes the pointer around and leaves the actual
953 representation to the library. Hence, we have to convert back to the
954 number of elements. */
955 if (compute_special_caf_types_size
)
956 size
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
, size_type_node
,
957 size
, TYPE_SIZE_UNIT (ptr_type_node
));
959 gfc_allocate_using_caf_lib (&alloc_block
, tmp
, size
, sub_caf_tree
,
960 status
, errmsg
, errlen
, caf_alloc_type
);
962 gfc_add_modify (&alloc_block
, mem
, fold_convert (TREE_TYPE (mem
),
963 gfc_conv_descriptor_data_get (tmp
)));
964 if (status
!= NULL_TREE
)
966 TREE_USED (label_finish
) = 1;
967 tmp
= build1_v (GOTO_EXPR
, label_finish
);
968 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
969 status
, build_zero_cst (TREE_TYPE (status
)));
970 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
971 gfc_unlikely (cond
, PRED_FORTRAN_FAIL_ALLOC
),
972 tmp
, build_empty_stmt (input_location
));
973 gfc_add_expr_to_block (&alloc_block
, tmp
);
977 gfc_allocate_using_malloc (&alloc_block
, mem
, size
, status
);
979 alloc
= gfc_finish_block (&alloc_block
);
981 /* If mem is not NULL, we issue a runtime error or set the
987 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
988 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
989 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
991 error
= gfc_trans_runtime_error (true, &expr
->where
,
992 "Attempting to allocate already"
993 " allocated variable '%s'",
997 error
= gfc_trans_runtime_error (true, NULL
,
998 "Attempting to allocate already allocated"
1001 if (status
!= NULL_TREE
)
1003 tree status_type
= TREE_TYPE (status
);
1005 error
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1006 status
, build_int_cst (status_type
, LIBERROR_ALLOCATION
));
1009 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, null_mem
,
1011 gfc_add_expr_to_block (block
, tmp
);
1015 /* Free a given variable. */
1018 gfc_call_free (tree var
)
1020 return build_call_expr_loc (input_location
,
1021 builtin_decl_explicit (BUILT_IN_FREE
),
1022 1, fold_convert (pvoid_type_node
, var
));
1026 /* Build a call to a FINAL procedure, which finalizes "var". */
1029 gfc_build_final_call (gfc_typespec ts
, gfc_expr
*final_wrapper
, gfc_expr
*var
,
1030 bool fini_coarray
, gfc_expr
*class_size
)
1034 tree final_fndecl
, array
, size
, tmp
;
1035 symbol_attribute attr
;
1037 gcc_assert (final_wrapper
->expr_type
== EXPR_VARIABLE
);
1040 gfc_start_block (&block
);
1041 gfc_init_se (&se
, NULL
);
1042 gfc_conv_expr (&se
, final_wrapper
);
1043 final_fndecl
= se
.expr
;
1044 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl
)))
1045 final_fndecl
= build_fold_indirect_ref_loc (input_location
, final_fndecl
);
1047 if (ts
.type
== BT_DERIVED
)
1051 gcc_assert (!class_size
);
1052 elem_size
= gfc_typenode_for_spec (&ts
);
1053 elem_size
= TYPE_SIZE_UNIT (elem_size
);
1054 size
= fold_convert (gfc_array_index_type
, elem_size
);
1056 gfc_init_se (&se
, NULL
);
1057 se
.want_pointer
= 1;
1060 se
.descriptor_only
= 1;
1061 gfc_conv_expr_descriptor (&se
, var
);
1066 gfc_conv_expr (&se
, var
);
1067 gcc_assert (se
.pre
.head
== NULL_TREE
&& se
.post
.head
== NULL_TREE
);
1070 /* No copy back needed, hence set attr's allocatable/pointer
1072 gfc_clear_attr (&attr
);
1073 gfc_init_se (&se
, NULL
);
1074 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
1075 gcc_assert (se
.post
.head
== NULL_TREE
);
1080 gfc_expr
*array_expr
;
1081 gcc_assert (class_size
);
1082 gfc_init_se (&se
, NULL
);
1083 gfc_conv_expr (&se
, class_size
);
1084 gfc_add_block_to_block (&block
, &se
.pre
);
1085 gcc_assert (se
.post
.head
== NULL_TREE
);
1088 array_expr
= gfc_copy_expr (var
);
1089 gfc_init_se (&se
, NULL
);
1090 se
.want_pointer
= 1;
1091 if (array_expr
->rank
)
1093 gfc_add_class_array_ref (array_expr
);
1094 se
.descriptor_only
= 1;
1095 gfc_conv_expr_descriptor (&se
, array_expr
);
1100 gfc_add_data_component (array_expr
);
1101 gfc_conv_expr (&se
, array_expr
);
1102 gfc_add_block_to_block (&block
, &se
.pre
);
1103 gcc_assert (se
.post
.head
== NULL_TREE
);
1106 if (!gfc_is_coarray (array_expr
))
1108 /* No copy back needed, hence set attr's allocatable/pointer
1110 gfc_clear_attr (&attr
);
1111 gfc_init_se (&se
, NULL
);
1112 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
1114 gcc_assert (se
.post
.head
== NULL_TREE
);
1116 gfc_free_expr (array_expr
);
1119 if (!POINTER_TYPE_P (TREE_TYPE (array
)))
1120 array
= gfc_build_addr_expr (NULL
, array
);
1122 gfc_add_block_to_block (&block
, &se
.pre
);
1123 tmp
= build_call_expr_loc (input_location
,
1124 final_fndecl
, 3, array
,
1125 size
, fini_coarray
? boolean_true_node
1126 : boolean_false_node
);
1127 gfc_add_block_to_block (&block
, &se
.post
);
1128 gfc_add_expr_to_block (&block
, tmp
);
1129 return gfc_finish_block (&block
);
1134 gfc_add_comp_finalizer_call (stmtblock_t
*block
, tree decl
, gfc_component
*comp
,
1139 tree final_fndecl
, size
, array
, tmp
, cond
;
1140 symbol_attribute attr
;
1141 gfc_expr
*final_expr
= NULL
;
1143 if (comp
->ts
.type
!= BT_DERIVED
&& comp
->ts
.type
!= BT_CLASS
)
1146 gfc_init_block (&block2
);
1148 if (comp
->ts
.type
== BT_DERIVED
)
1150 if (comp
->attr
.pointer
)
1153 gfc_is_finalizable (comp
->ts
.u
.derived
, &final_expr
);
1157 gfc_init_se (&se
, NULL
);
1158 gfc_conv_expr (&se
, final_expr
);
1159 final_fndecl
= se
.expr
;
1160 size
= gfc_typenode_for_spec (&comp
->ts
);
1161 size
= TYPE_SIZE_UNIT (size
);
1162 size
= fold_convert (gfc_array_index_type
, size
);
1166 else /* comp->ts.type == BT_CLASS. */
1168 if (CLASS_DATA (comp
)->attr
.class_pointer
)
1171 gfc_is_finalizable (CLASS_DATA (comp
)->ts
.u
.derived
, &final_expr
);
1172 final_fndecl
= gfc_class_vtab_final_get (decl
);
1173 size
= gfc_class_vtab_size_get (decl
);
1174 array
= gfc_class_data_get (decl
);
1177 if (comp
->attr
.allocatable
1178 || (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)->attr
.allocatable
))
1180 tmp
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array
))
1181 ? gfc_conv_descriptor_data_get (array
) : array
;
1182 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1183 tmp
, fold_convert (TREE_TYPE (tmp
),
1184 null_pointer_node
));
1187 cond
= logical_true_node
;
1189 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array
)))
1191 gfc_clear_attr (&attr
);
1192 gfc_init_se (&se
, NULL
);
1193 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
1194 gfc_add_block_to_block (&block2
, &se
.pre
);
1195 gcc_assert (se
.post
.head
== NULL_TREE
);
1198 if (!POINTER_TYPE_P (TREE_TYPE (array
)))
1199 array
= gfc_build_addr_expr (NULL
, array
);
1203 tmp
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1205 fold_convert (TREE_TYPE (final_fndecl
),
1206 null_pointer_node
));
1207 cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
1208 logical_type_node
, cond
, tmp
);
1211 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl
)))
1212 final_fndecl
= build_fold_indirect_ref_loc (input_location
, final_fndecl
);
1214 tmp
= build_call_expr_loc (input_location
,
1215 final_fndecl
, 3, array
,
1216 size
, fini_coarray
? boolean_true_node
1217 : boolean_false_node
);
1218 gfc_add_expr_to_block (&block2
, tmp
);
1219 tmp
= gfc_finish_block (&block2
);
1221 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
, tmp
,
1222 build_empty_stmt (input_location
));
1223 gfc_add_expr_to_block (block
, tmp
);
1229 /* Add a call to the finalizer, using the passed *expr. Returns
1230 true when a finalizer call has been inserted. */
1233 gfc_add_finalizer_call (stmtblock_t
*block
, gfc_expr
*expr2
)
1238 gfc_expr
*final_expr
= NULL
;
1239 gfc_expr
*elem_size
= NULL
;
1240 bool has_finalizer
= false;
1242 if (!expr2
|| (expr2
->ts
.type
!= BT_DERIVED
&& expr2
->ts
.type
!= BT_CLASS
))
1245 if (expr2
->ts
.type
== BT_DERIVED
)
1247 gfc_is_finalizable (expr2
->ts
.u
.derived
, &final_expr
);
1252 /* If we have a class array, we need go back to the class
1254 expr
= gfc_copy_expr (expr2
);
1256 if (expr
->ref
&& expr
->ref
->next
&& !expr
->ref
->next
->next
1257 && expr
->ref
->next
->type
== REF_ARRAY
1258 && expr
->ref
->type
== REF_COMPONENT
1259 && strcmp (expr
->ref
->u
.c
.component
->name
, "_data") == 0)
1261 gfc_free_ref_list (expr
->ref
);
1265 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
1266 if (ref
->next
&& ref
->next
->next
&& !ref
->next
->next
->next
1267 && ref
->next
->next
->type
== REF_ARRAY
1268 && ref
->next
->type
== REF_COMPONENT
1269 && strcmp (ref
->next
->u
.c
.component
->name
, "_data") == 0)
1271 gfc_free_ref_list (ref
->next
);
1275 if (expr
->ts
.type
== BT_CLASS
)
1277 has_finalizer
= gfc_is_finalizable (expr
->ts
.u
.derived
, NULL
);
1279 if (!expr2
->rank
&& !expr2
->ref
&& CLASS_DATA (expr2
->symtree
->n
.sym
)->as
)
1280 expr
->rank
= CLASS_DATA (expr2
->symtree
->n
.sym
)->as
->rank
;
1282 final_expr
= gfc_copy_expr (expr
);
1283 gfc_add_vptr_component (final_expr
);
1284 gfc_add_final_component (final_expr
);
1286 elem_size
= gfc_copy_expr (expr
);
1287 gfc_add_vptr_component (elem_size
);
1288 gfc_add_size_component (elem_size
);
1291 gcc_assert (final_expr
->expr_type
== EXPR_VARIABLE
);
1293 tmp
= gfc_build_final_call (expr
->ts
, final_expr
, expr
,
1296 if (expr
->ts
.type
== BT_CLASS
&& !has_finalizer
)
1301 gfc_init_se (&se
, NULL
);
1302 se
.want_pointer
= 1;
1303 gfc_conv_expr (&se
, final_expr
);
1304 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1305 se
.expr
, build_int_cst (TREE_TYPE (se
.expr
), 0));
1307 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1308 but already sym->_vtab itself. */
1309 if (UNLIMITED_POLY (expr
))
1312 gfc_expr
*vptr_expr
;
1314 vptr_expr
= gfc_copy_expr (expr
);
1315 gfc_add_vptr_component (vptr_expr
);
1317 gfc_init_se (&se
, NULL
);
1318 se
.want_pointer
= 1;
1319 gfc_conv_expr (&se
, vptr_expr
);
1320 gfc_free_expr (vptr_expr
);
1322 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1324 build_int_cst (TREE_TYPE (se
.expr
), 0));
1325 cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
1326 logical_type_node
, cond2
, cond
);
1329 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1330 cond
, tmp
, build_empty_stmt (input_location
));
1333 gfc_add_expr_to_block (block
, tmp
);
1339 /* User-deallocate; we emit the code directly from the front-end, and the
1340 logic is the same as the previous library function:
1343 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1350 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1360 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1361 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1362 even when no status variable is passed to us (this is used for
1363 unconditional deallocation generated by the front-end at end of
1366 If a runtime-message is possible, `expr' must point to the original
1367 expression being deallocated for its locus and variable name.
1369 For coarrays, "pointer" must be the array descriptor and not its
1372 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1373 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1374 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1377 gfc_deallocate_with_status (tree pointer
, tree status
, tree errmsg
,
1378 tree errlen
, tree label_finish
,
1379 bool can_fail
, gfc_expr
* expr
,
1380 int coarray_dealloc_mode
, tree add_when_allocated
,
1383 stmtblock_t null
, non_null
;
1384 tree cond
, tmp
, error
;
1385 tree status_type
= NULL_TREE
;
1386 tree token
= NULL_TREE
;
1387 gfc_coarray_deregtype caf_dereg_type
= GFC_CAF_COARRAY_DEREGISTER
;
1389 if (coarray_dealloc_mode
>= GFC_CAF_COARRAY_ANALYZE
)
1391 if (flag_coarray
== GFC_FCOARRAY_LIB
)
1397 tree caf_type
, caf_decl
= pointer
;
1398 pointer
= gfc_conv_descriptor_data_get (caf_decl
);
1399 caf_type
= TREE_TYPE (caf_decl
);
1400 STRIP_NOPS (pointer
);
1401 if (GFC_DESCRIPTOR_TYPE_P (caf_type
))
1402 token
= gfc_conv_descriptor_token (caf_decl
);
1403 else if (DECL_LANG_SPECIFIC (caf_decl
)
1404 && GFC_DECL_TOKEN (caf_decl
) != NULL_TREE
)
1405 token
= GFC_DECL_TOKEN (caf_decl
);
1408 gcc_assert (GFC_ARRAY_TYPE_P (caf_type
)
1409 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
)
1411 token
= GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
);
1415 if (coarray_dealloc_mode
== GFC_CAF_COARRAY_ANALYZE
)
1418 if (expr
&& !gfc_caf_attr (expr
, false, &comp_ref
).coarray_comp
1420 caf_dereg_type
= GFC_CAF_COARRAY_DEALLOCATE_ONLY
;
1421 // else do a deregister as set by default.
1424 caf_dereg_type
= (enum gfc_coarray_deregtype
) coarray_dealloc_mode
;
1426 else if (flag_coarray
== GFC_FCOARRAY_SINGLE
)
1427 pointer
= gfc_conv_descriptor_data_get (pointer
);
1429 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer
)))
1430 pointer
= gfc_conv_descriptor_data_get (pointer
);
1432 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
, pointer
,
1433 build_int_cst (TREE_TYPE (pointer
), 0));
1435 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1436 we emit a runtime error. */
1437 gfc_start_block (&null
);
1442 gcc_assert (expr
&& expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
1444 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
1445 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
1447 error
= gfc_trans_runtime_error (true, &expr
->where
,
1448 "Attempt to DEALLOCATE unallocated '%s'",
1452 error
= build_empty_stmt (input_location
);
1454 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1458 status_type
= TREE_TYPE (TREE_TYPE (status
));
1459 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1460 status
, build_int_cst (TREE_TYPE (status
), 0));
1461 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1462 fold_build1_loc (input_location
, INDIRECT_REF
,
1463 status_type
, status
),
1464 build_int_cst (status_type
, 1));
1465 error
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1469 gfc_add_expr_to_block (&null
, error
);
1471 /* When POINTER is not NULL, we free it. */
1472 gfc_start_block (&non_null
);
1473 if (add_when_allocated
)
1474 gfc_add_expr_to_block (&non_null
, add_when_allocated
);
1475 gfc_add_finalizer_call (&non_null
, expr
);
1476 if (coarray_dealloc_mode
== GFC_CAF_COARRAY_NOCOARRAY
1477 || flag_coarray
!= GFC_FCOARRAY_LIB
)
1479 tmp
= build_call_expr_loc (input_location
,
1480 builtin_decl_explicit (BUILT_IN_FREE
), 1,
1481 fold_convert (pvoid_type_node
, pointer
));
1482 gfc_add_expr_to_block (&non_null
, tmp
);
1483 gfc_add_modify (&non_null
, pointer
, build_int_cst (TREE_TYPE (pointer
),
1486 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1488 /* We set STATUS to zero if it is present. */
1489 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1492 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1494 build_int_cst (TREE_TYPE (status
), 0));
1495 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1496 fold_build1_loc (input_location
, INDIRECT_REF
,
1497 status_type
, status
),
1498 build_int_cst (status_type
, 0));
1499 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1500 gfc_unlikely (cond2
, PRED_FORTRAN_FAIL_ALLOC
),
1501 tmp
, build_empty_stmt (input_location
));
1502 gfc_add_expr_to_block (&non_null
, tmp
);
1507 tree cond2
, pstat
= null_pointer_node
;
1509 if (errmsg
== NULL_TREE
)
1511 gcc_assert (errlen
== NULL_TREE
);
1512 errmsg
= null_pointer_node
;
1513 errlen
= build_zero_cst (integer_type_node
);
1517 gcc_assert (errlen
!= NULL_TREE
);
1518 if (!POINTER_TYPE_P (TREE_TYPE (errmsg
)))
1519 errmsg
= gfc_build_addr_expr (NULL_TREE
, errmsg
);
1522 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1524 gcc_assert (status_type
== integer_type_node
);
1528 token
= gfc_build_addr_expr (NULL_TREE
, token
);
1529 gcc_assert (caf_dereg_type
> GFC_CAF_COARRAY_ANALYZE
);
1530 tmp
= build_call_expr_loc (input_location
,
1531 gfor_fndecl_caf_deregister
, 5,
1532 token
, build_int_cst (integer_type_node
,
1534 pstat
, errmsg
, errlen
);
1535 gfc_add_expr_to_block (&non_null
, tmp
);
1537 /* It guarantees memory consistency within the same segment */
1538 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory"),
1539 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
1540 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
1541 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
1542 ASM_VOLATILE_P (tmp
) = 1;
1543 gfc_add_expr_to_block (&non_null
, tmp
);
1545 if (status
!= NULL_TREE
)
1547 tree stat
= build_fold_indirect_ref_loc (input_location
, status
);
1548 tree nullify
= fold_build2_loc (input_location
, MODIFY_EXPR
,
1549 void_type_node
, pointer
,
1550 build_int_cst (TREE_TYPE (pointer
),
1553 TREE_USED (label_finish
) = 1;
1554 tmp
= build1_v (GOTO_EXPR
, label_finish
);
1555 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1556 stat
, build_zero_cst (TREE_TYPE (stat
)));
1557 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1558 gfc_unlikely (cond2
, PRED_FORTRAN_REALLOC
),
1560 gfc_add_expr_to_block (&non_null
, tmp
);
1563 gfc_add_modify (&non_null
, pointer
, build_int_cst (TREE_TYPE (pointer
),
1567 return fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
1568 gfc_finish_block (&null
),
1569 gfc_finish_block (&non_null
));
1573 /* Generate code for deallocation of allocatable scalars (variables or
1574 components). Before the object itself is freed, any allocatable
1575 subcomponents are being deallocated. */
1578 gfc_deallocate_scalar_with_status (tree pointer
, tree status
, tree label_finish
,
1579 bool can_fail
, gfc_expr
* expr
,
1580 gfc_typespec ts
, bool coarray
)
1582 stmtblock_t null
, non_null
;
1583 tree cond
, tmp
, error
;
1584 bool finalizable
, comp_ref
;
1585 gfc_coarray_deregtype caf_dereg_type
= GFC_CAF_COARRAY_DEREGISTER
;
1587 if (coarray
&& expr
&& !gfc_caf_attr (expr
, false, &comp_ref
).coarray_comp
1589 caf_dereg_type
= GFC_CAF_COARRAY_DEALLOCATE_ONLY
;
1591 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
, pointer
,
1592 build_int_cst (TREE_TYPE (pointer
), 0));
1594 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1595 we emit a runtime error. */
1596 gfc_start_block (&null
);
1601 gcc_assert (expr
&& expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
1603 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
1604 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
1606 error
= gfc_trans_runtime_error (true, &expr
->where
,
1607 "Attempt to DEALLOCATE unallocated '%s'",
1611 error
= build_empty_stmt (input_location
);
1613 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1615 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1618 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1619 status
, build_int_cst (TREE_TYPE (status
), 0));
1620 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1621 fold_build1_loc (input_location
, INDIRECT_REF
,
1622 status_type
, status
),
1623 build_int_cst (status_type
, 1));
1624 error
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1627 gfc_add_expr_to_block (&null
, error
);
1629 /* When POINTER is not NULL, we free it. */
1630 gfc_start_block (&non_null
);
1632 /* Free allocatable components. */
1633 finalizable
= gfc_add_finalizer_call (&non_null
, expr
);
1634 if (!finalizable
&& ts
.type
== BT_DERIVED
&& ts
.u
.derived
->attr
.alloc_comp
)
1636 int caf_mode
= coarray
1637 ? ((caf_dereg_type
== GFC_CAF_COARRAY_DEALLOCATE_ONLY
1638 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY
: 0)
1639 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1640 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY
)
1642 if (coarray
&& GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer
)))
1643 tmp
= gfc_conv_descriptor_data_get (pointer
);
1645 tmp
= build_fold_indirect_ref_loc (input_location
, pointer
);
1646 tmp
= gfc_deallocate_alloc_comp (ts
.u
.derived
, tmp
, 0, caf_mode
);
1647 gfc_add_expr_to_block (&non_null
, tmp
);
1650 if (!coarray
|| flag_coarray
== GFC_FCOARRAY_SINGLE
)
1652 tmp
= build_call_expr_loc (input_location
,
1653 builtin_decl_explicit (BUILT_IN_FREE
), 1,
1654 fold_convert (pvoid_type_node
, pointer
));
1655 gfc_add_expr_to_block (&non_null
, tmp
);
1657 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1659 /* We set STATUS to zero if it is present. */
1660 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1663 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1665 build_int_cst (TREE_TYPE (status
), 0));
1666 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1667 fold_build1_loc (input_location
, INDIRECT_REF
,
1668 status_type
, status
),
1669 build_int_cst (status_type
, 0));
1670 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1671 cond2
, tmp
, build_empty_stmt (input_location
));
1672 gfc_add_expr_to_block (&non_null
, tmp
);
1678 tree pstat
= null_pointer_node
;
1681 gfc_init_se (&se
, NULL
);
1682 token
= gfc_get_ultimate_alloc_ptr_comps_caf_token (&se
, expr
);
1683 gcc_assert (token
!= NULL_TREE
);
1685 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1687 gcc_assert (TREE_TYPE (TREE_TYPE (status
)) == integer_type_node
);
1691 tmp
= build_call_expr_loc (input_location
,
1692 gfor_fndecl_caf_deregister
, 5,
1693 token
, build_int_cst (integer_type_node
,
1695 pstat
, null_pointer_node
, integer_zero_node
);
1696 gfc_add_expr_to_block (&non_null
, tmp
);
1698 /* It guarantees memory consistency within the same segment. */
1699 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory");
1700 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
1701 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
1702 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
1703 ASM_VOLATILE_P (tmp
) = 1;
1704 gfc_add_expr_to_block (&non_null
, tmp
);
1706 if (status
!= NULL_TREE
)
1708 tree stat
= build_fold_indirect_ref_loc (input_location
, status
);
1711 TREE_USED (label_finish
) = 1;
1712 tmp
= build1_v (GOTO_EXPR
, label_finish
);
1713 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1714 stat
, build_zero_cst (TREE_TYPE (stat
)));
1715 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1716 gfc_unlikely (cond2
, PRED_FORTRAN_REALLOC
),
1717 tmp
, build_empty_stmt (input_location
));
1718 gfc_add_expr_to_block (&non_null
, tmp
);
1722 return fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
1723 gfc_finish_block (&null
),
1724 gfc_finish_block (&non_null
));
1727 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1728 following pseudo-code:
1731 internal_realloc (void *mem, size_t size)
1733 res = realloc (mem, size);
1734 if (!res && size != 0)
1735 _gfortran_os_error ("Allocation would exceed memory limit");
1740 gfc_call_realloc (stmtblock_t
* block
, tree mem
, tree size
)
1742 tree res
, nonzero
, null_result
, tmp
;
1743 tree type
= TREE_TYPE (mem
);
1745 /* Only evaluate the size once. */
1746 size
= save_expr (fold_convert (size_type_node
, size
));
1748 /* Create a variable to hold the result. */
1749 res
= gfc_create_var (type
, NULL
);
1751 /* Call realloc and check the result. */
1752 tmp
= build_call_expr_loc (input_location
,
1753 builtin_decl_explicit (BUILT_IN_REALLOC
), 2,
1754 fold_convert (pvoid_type_node
, mem
), size
);
1755 gfc_add_modify (block
, res
, fold_convert (type
, tmp
));
1756 null_result
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
1757 res
, build_int_cst (pvoid_type_node
, 0));
1758 nonzero
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
, size
,
1759 build_int_cst (size_type_node
, 0));
1760 null_result
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, logical_type_node
,
1761 null_result
, nonzero
);
1762 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1764 trans_os_error_at (NULL
,
1765 "Error reallocating to %lu bytes",
1767 (long_unsigned_type_node
, size
)),
1768 build_empty_stmt (input_location
));
1769 gfc_add_expr_to_block (block
, tmp
);
1775 /* Add an expression to another one, either at the front or the back. */
1778 add_expr_to_chain (tree
* chain
, tree expr
, bool front
)
1780 if (expr
== NULL_TREE
|| IS_EMPTY_STMT (expr
))
1785 if (TREE_CODE (*chain
) != STATEMENT_LIST
)
1791 append_to_statement_list (tmp
, chain
);
1796 tree_stmt_iterator i
;
1798 i
= tsi_start (*chain
);
1799 tsi_link_before (&i
, expr
, TSI_CONTINUE_LINKING
);
1802 append_to_statement_list (expr
, chain
);
1809 /* Add a statement at the end of a block. */
1812 gfc_add_expr_to_block (stmtblock_t
* block
, tree expr
)
1815 add_expr_to_chain (&block
->head
, expr
, false);
1819 /* Add a statement at the beginning of a block. */
1822 gfc_prepend_expr_to_block (stmtblock_t
* block
, tree expr
)
1825 add_expr_to_chain (&block
->head
, expr
, true);
1829 /* Add a block the end of a block. */
1832 gfc_add_block_to_block (stmtblock_t
* block
, stmtblock_t
* append
)
1834 gcc_assert (append
);
1835 gcc_assert (!append
->has_scope
);
1837 gfc_add_expr_to_block (block
, append
->head
);
1838 append
->head
= NULL_TREE
;
1842 /* Save the current locus. The structure may not be complete, and should
1843 only be used with gfc_restore_backend_locus. */
1846 gfc_save_backend_locus (locus
* loc
)
1848 loc
->lb
= XCNEW (gfc_linebuf
);
1849 loc
->lb
->location
= input_location
;
1850 loc
->lb
->file
= gfc_current_backend_file
;
1854 /* Set the current locus. */
1857 gfc_set_backend_locus (locus
* loc
)
1859 gfc_current_backend_file
= loc
->lb
->file
;
1860 input_location
= gfc_get_location (loc
);
1864 /* Restore the saved locus. Only used in conjunction with
1865 gfc_save_backend_locus, to free the memory when we are done. */
1868 gfc_restore_backend_locus (locus
* loc
)
1870 /* This only restores the information captured by gfc_save_backend_locus,
1871 intentionally does not use gfc_get_location. */
1872 input_location
= loc
->lb
->location
;
1873 gfc_current_backend_file
= loc
->lb
->file
;
1878 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
1879 This static function is wrapped by gfc_trans_code_cond and
1883 trans_code (gfc_code
* code
, tree cond
)
1889 return build_empty_stmt (input_location
);
1891 gfc_start_block (&block
);
1893 /* Translate statements one by one into GENERIC trees until we reach
1894 the end of this gfc_code branch. */
1895 for (; code
; code
= code
->next
)
1897 if (code
->here
!= 0)
1899 res
= gfc_trans_label_here (code
);
1900 gfc_add_expr_to_block (&block
, res
);
1903 gfc_current_locus
= code
->loc
;
1904 gfc_set_backend_locus (&code
->loc
);
1909 case EXEC_END_BLOCK
:
1910 case EXEC_END_NESTED_BLOCK
:
1911 case EXEC_END_PROCEDURE
:
1916 res
= gfc_trans_assign (code
);
1919 case EXEC_LABEL_ASSIGN
:
1920 res
= gfc_trans_label_assign (code
);
1923 case EXEC_POINTER_ASSIGN
:
1924 res
= gfc_trans_pointer_assign (code
);
1927 case EXEC_INIT_ASSIGN
:
1928 if (code
->expr1
->ts
.type
== BT_CLASS
)
1929 res
= gfc_trans_class_init_assign (code
);
1931 res
= gfc_trans_init_assign (code
);
1939 res
= gfc_trans_critical (code
);
1943 res
= gfc_trans_cycle (code
);
1947 res
= gfc_trans_exit (code
);
1951 res
= gfc_trans_goto (code
);
1955 res
= gfc_trans_entry (code
);
1959 res
= gfc_trans_pause (code
);
1963 case EXEC_ERROR_STOP
:
1964 res
= gfc_trans_stop (code
, code
->op
== EXEC_ERROR_STOP
);
1968 /* For MVBITS we've got the special exception that we need a
1969 dependency check, too. */
1971 bool is_mvbits
= false;
1973 if (code
->resolved_isym
)
1975 res
= gfc_conv_intrinsic_subroutine (code
);
1976 if (res
!= NULL_TREE
)
1980 if (code
->resolved_isym
1981 && code
->resolved_isym
->id
== GFC_ISYM_MVBITS
)
1984 res
= gfc_trans_call (code
, is_mvbits
, NULL_TREE
,
1990 res
= gfc_trans_call (code
, false, NULL_TREE
,
1994 case EXEC_ASSIGN_CALL
:
1995 res
= gfc_trans_call (code
, true, NULL_TREE
,
2000 res
= gfc_trans_return (code
);
2004 res
= gfc_trans_if (code
);
2007 case EXEC_ARITHMETIC_IF
:
2008 res
= gfc_trans_arithmetic_if (code
);
2012 res
= gfc_trans_block_construct (code
);
2016 res
= gfc_trans_do (code
, cond
);
2019 case EXEC_DO_CONCURRENT
:
2020 res
= gfc_trans_do_concurrent (code
);
2024 res
= gfc_trans_do_while (code
);
2028 res
= gfc_trans_select (code
);
2031 case EXEC_SELECT_TYPE
:
2032 res
= gfc_trans_select_type (code
);
2035 case EXEC_SELECT_RANK
:
2036 res
= gfc_trans_select_rank (code
);
2040 res
= gfc_trans_flush (code
);
2044 case EXEC_SYNC_IMAGES
:
2045 case EXEC_SYNC_MEMORY
:
2046 res
= gfc_trans_sync (code
, code
->op
);
2051 res
= gfc_trans_lock_unlock (code
, code
->op
);
2054 case EXEC_EVENT_POST
:
2055 case EXEC_EVENT_WAIT
:
2056 res
= gfc_trans_event_post_wait (code
, code
->op
);
2059 case EXEC_FAIL_IMAGE
:
2060 res
= gfc_trans_fail_image (code
);
2064 res
= gfc_trans_forall (code
);
2067 case EXEC_FORM_TEAM
:
2068 res
= gfc_trans_form_team (code
);
2071 case EXEC_CHANGE_TEAM
:
2072 res
= gfc_trans_change_team (code
);
2076 res
= gfc_trans_end_team (code
);
2079 case EXEC_SYNC_TEAM
:
2080 res
= gfc_trans_sync_team (code
);
2084 res
= gfc_trans_where (code
);
2088 res
= gfc_trans_allocate (code
);
2091 case EXEC_DEALLOCATE
:
2092 res
= gfc_trans_deallocate (code
);
2096 res
= gfc_trans_open (code
);
2100 res
= gfc_trans_close (code
);
2104 res
= gfc_trans_read (code
);
2108 res
= gfc_trans_write (code
);
2112 res
= gfc_trans_iolength (code
);
2115 case EXEC_BACKSPACE
:
2116 res
= gfc_trans_backspace (code
);
2120 res
= gfc_trans_endfile (code
);
2124 res
= gfc_trans_inquire (code
);
2128 res
= gfc_trans_wait (code
);
2132 res
= gfc_trans_rewind (code
);
2136 res
= gfc_trans_transfer (code
);
2140 res
= gfc_trans_dt_end (code
);
2143 case EXEC_OMP_ATOMIC
:
2144 case EXEC_OMP_BARRIER
:
2145 case EXEC_OMP_CANCEL
:
2146 case EXEC_OMP_CANCELLATION_POINT
:
2147 case EXEC_OMP_CRITICAL
:
2148 case EXEC_OMP_DEPOBJ
:
2149 case EXEC_OMP_DISTRIBUTE
:
2150 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
2151 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
2152 case EXEC_OMP_DISTRIBUTE_SIMD
:
2154 case EXEC_OMP_DO_SIMD
:
2156 case EXEC_OMP_ERROR
:
2157 case EXEC_OMP_FLUSH
:
2158 case EXEC_OMP_MASKED
:
2159 case EXEC_OMP_MASKED_TASKLOOP
:
2160 case EXEC_OMP_MASKED_TASKLOOP_SIMD
:
2161 case EXEC_OMP_MASTER
:
2162 case EXEC_OMP_MASTER_TASKLOOP
:
2163 case EXEC_OMP_MASTER_TASKLOOP_SIMD
:
2164 case EXEC_OMP_ORDERED
:
2165 case EXEC_OMP_PARALLEL
:
2166 case EXEC_OMP_PARALLEL_DO
:
2167 case EXEC_OMP_PARALLEL_DO_SIMD
:
2168 case EXEC_OMP_PARALLEL_LOOP
:
2169 case EXEC_OMP_PARALLEL_MASKED
:
2170 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP
:
2171 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD
:
2172 case EXEC_OMP_PARALLEL_MASTER
:
2173 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP
:
2174 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD
:
2175 case EXEC_OMP_PARALLEL_SECTIONS
:
2176 case EXEC_OMP_PARALLEL_WORKSHARE
:
2177 case EXEC_OMP_SCOPE
:
2178 case EXEC_OMP_SECTIONS
:
2180 case EXEC_OMP_SINGLE
:
2181 case EXEC_OMP_TARGET
:
2182 case EXEC_OMP_TARGET_DATA
:
2183 case EXEC_OMP_TARGET_ENTER_DATA
:
2184 case EXEC_OMP_TARGET_EXIT_DATA
:
2185 case EXEC_OMP_TARGET_PARALLEL
:
2186 case EXEC_OMP_TARGET_PARALLEL_DO
:
2187 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
2188 case EXEC_OMP_TARGET_PARALLEL_LOOP
:
2189 case EXEC_OMP_TARGET_SIMD
:
2190 case EXEC_OMP_TARGET_TEAMS
:
2191 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
2192 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
2193 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
2194 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
2195 case EXEC_OMP_TARGET_TEAMS_LOOP
:
2196 case EXEC_OMP_TARGET_UPDATE
:
2198 case EXEC_OMP_TASKGROUP
:
2199 case EXEC_OMP_TASKLOOP
:
2200 case EXEC_OMP_TASKLOOP_SIMD
:
2201 case EXEC_OMP_TASKWAIT
:
2202 case EXEC_OMP_TASKYIELD
:
2203 case EXEC_OMP_TEAMS
:
2204 case EXEC_OMP_TEAMS_DISTRIBUTE
:
2205 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
2206 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
2207 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
2208 case EXEC_OMP_TEAMS_LOOP
:
2209 case EXEC_OMP_WORKSHARE
:
2210 res
= gfc_trans_omp_directive (code
);
2213 case EXEC_OACC_CACHE
:
2214 case EXEC_OACC_WAIT
:
2215 case EXEC_OACC_UPDATE
:
2216 case EXEC_OACC_LOOP
:
2217 case EXEC_OACC_HOST_DATA
:
2218 case EXEC_OACC_DATA
:
2219 case EXEC_OACC_KERNELS
:
2220 case EXEC_OACC_KERNELS_LOOP
:
2221 case EXEC_OACC_PARALLEL
:
2222 case EXEC_OACC_PARALLEL_LOOP
:
2223 case EXEC_OACC_SERIAL
:
2224 case EXEC_OACC_SERIAL_LOOP
:
2225 case EXEC_OACC_ENTER_DATA
:
2226 case EXEC_OACC_EXIT_DATA
:
2227 case EXEC_OACC_ATOMIC
:
2228 case EXEC_OACC_DECLARE
:
2229 res
= gfc_trans_oacc_directive (code
);
2233 gfc_internal_error ("gfc_trans_code(): Bad statement code");
2236 gfc_set_backend_locus (&code
->loc
);
2238 if (res
!= NULL_TREE
&& ! IS_EMPTY_STMT (res
))
2240 if (TREE_CODE (res
) != STATEMENT_LIST
)
2241 SET_EXPR_LOCATION (res
, input_location
);
2243 /* Add the new statement to the block. */
2244 gfc_add_expr_to_block (&block
, res
);
2248 /* Return the finished block. */
2249 return gfc_finish_block (&block
);
2253 /* Translate an executable statement with condition, cond. The condition is
2254 used by gfc_trans_do to test for IO result conditions inside implied
2255 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
2258 gfc_trans_code_cond (gfc_code
* code
, tree cond
)
2260 return trans_code (code
, cond
);
2263 /* Translate an executable statement without condition. */
2266 gfc_trans_code (gfc_code
* code
)
2268 return trans_code (code
, NULL_TREE
);
2272 /* This function is called after a complete program unit has been parsed
2276 gfc_generate_code (gfc_namespace
* ns
)
2279 if (ns
->is_block_data
)
2281 gfc_generate_block_data (ns
);
2285 gfc_generate_function_code (ns
);
2289 /* This function is called after a complete module has been parsed
2293 gfc_generate_module_code (gfc_namespace
* ns
)
2296 struct module_htab_entry
*entry
;
2298 gcc_assert (ns
->proc_name
->backend_decl
== NULL
);
2299 ns
->proc_name
->backend_decl
2300 = build_decl (gfc_get_location (&ns
->proc_name
->declared_at
),
2301 NAMESPACE_DECL
, get_identifier (ns
->proc_name
->name
),
2303 entry
= gfc_find_module (ns
->proc_name
->name
);
2304 if (entry
->namespace_decl
)
2305 /* Buggy sourcecode, using a module before defining it? */
2306 entry
->decls
->empty ();
2307 entry
->namespace_decl
= ns
->proc_name
->backend_decl
;
2309 gfc_generate_module_vars (ns
);
2311 /* We need to generate all module function prototypes first, to allow
2313 for (n
= ns
->contained
; n
; n
= n
->sibling
)
2320 gfc_create_function_decl (n
, false);
2321 DECL_CONTEXT (n
->proc_name
->backend_decl
) = ns
->proc_name
->backend_decl
;
2322 gfc_module_add_decl (entry
, n
->proc_name
->backend_decl
);
2323 for (el
= ns
->entries
; el
; el
= el
->next
)
2325 DECL_CONTEXT (el
->sym
->backend_decl
) = ns
->proc_name
->backend_decl
;
2326 gfc_module_add_decl (entry
, el
->sym
->backend_decl
);
2330 for (n
= ns
->contained
; n
; n
= n
->sibling
)
2335 gfc_generate_function_code (n
);
2340 /* Initialize an init/cleanup block with existing code. */
2343 gfc_start_wrapped_block (gfc_wrapped_block
* block
, tree code
)
2347 block
->init
= NULL_TREE
;
2349 block
->cleanup
= NULL_TREE
;
2353 /* Add a new pair of initializers/clean-up code. */
2356 gfc_add_init_cleanup (gfc_wrapped_block
* block
, tree init
, tree cleanup
)
2360 /* The new pair of init/cleanup should be "wrapped around" the existing
2361 block of code, thus the initialization is added to the front and the
2362 cleanup to the back. */
2363 add_expr_to_chain (&block
->init
, init
, true);
2364 add_expr_to_chain (&block
->cleanup
, cleanup
, false);
2368 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2371 gfc_finish_wrapped_block (gfc_wrapped_block
* block
)
2377 /* Build the final expression. For this, just add init and body together,
2378 and put clean-up with that into a TRY_FINALLY_EXPR. */
2379 result
= block
->init
;
2380 add_expr_to_chain (&result
, block
->code
, false);
2382 result
= build2_loc (input_location
, TRY_FINALLY_EXPR
, void_type_node
,
2383 result
, block
->cleanup
);
2385 /* Clear the block. */
2386 block
->init
= NULL_TREE
;
2387 block
->code
= NULL_TREE
;
2388 block
->cleanup
= NULL_TREE
;
2394 /* Helper function for marking a boolean expression tree as unlikely. */
2397 gfc_unlikely (tree cond
, enum br_predictor predictor
)
2403 cond
= fold_convert (long_integer_type_node
, cond
);
2404 tmp
= build_zero_cst (long_integer_type_node
);
2405 cond
= build_call_expr_loc (input_location
,
2406 builtin_decl_explicit (BUILT_IN_EXPECT
),
2408 build_int_cst (integer_type_node
,
2415 /* Helper function for marking a boolean expression tree as likely. */
2418 gfc_likely (tree cond
, enum br_predictor predictor
)
2424 cond
= fold_convert (long_integer_type_node
, cond
);
2425 tmp
= build_one_cst (long_integer_type_node
);
2426 cond
= build_call_expr_loc (input_location
,
2427 builtin_decl_explicit (BUILT_IN_EXPECT
),
2429 build_int_cst (integer_type_node
,
2436 /* Get the string length for a deferred character length component. */
2439 gfc_deferred_strlen (gfc_component
*c
, tree
*decl
)
2441 char name
[GFC_MAX_SYMBOL_LEN
+9];
2442 gfc_component
*strlen
;
2443 if (!(c
->ts
.type
== BT_CHARACTER
2444 && (c
->ts
.deferred
|| c
->attr
.pdt_string
)))
2446 sprintf (name
, "_%s_length", c
->name
);
2447 for (strlen
= c
; strlen
; strlen
= strlen
->next
)
2448 if (strcmp (strlen
->name
, name
) == 0)
2450 *decl
= strlen
? strlen
->backend_decl
: NULL_TREE
;
2451 return strlen
!= NULL
;