1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2018 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");
48 const char gfc_msg_wrong_return
[] = N_("Incorrect function return value");
51 /* Advance along TREE_CHAIN n times. */
54 gfc_advance_chain (tree t
, int n
)
58 gcc_assert (t
!= NULL_TREE
);
64 /* Creates a variable declaration with a given TYPE. */
67 gfc_create_var_np (tree type
, const char *prefix
)
71 t
= create_tmp_var_raw (type
, prefix
);
73 /* No warnings for anonymous variables. */
75 TREE_NO_WARNING (t
) = 1;
81 /* Like above, but also adds it to the current scope. */
84 gfc_create_var (tree type
, const char *prefix
)
88 tmp
= gfc_create_var_np (type
, prefix
);
96 /* If the expression is not constant, evaluate it now. We assign the
97 result of the expression to an artificially created variable VAR, and
98 return a pointer to the VAR_DECL node for this variable. */
101 gfc_evaluate_now_loc (location_t loc
, tree expr
, stmtblock_t
* pblock
)
105 if (CONSTANT_CLASS_P (expr
))
108 var
= gfc_create_var (TREE_TYPE (expr
), NULL
);
109 gfc_add_modify_loc (loc
, pblock
, var
, expr
);
116 gfc_evaluate_now (tree expr
, stmtblock_t
* pblock
)
118 return gfc_evaluate_now_loc (input_location
, expr
, pblock
);
122 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
123 A MODIFY_EXPR is an assignment:
127 gfc_add_modify_loc (location_t loc
, stmtblock_t
* pblock
, tree lhs
, tree rhs
)
132 t1
= TREE_TYPE (rhs
);
133 t2
= TREE_TYPE (lhs
);
134 /* Make sure that the types of the rhs and the lhs are compatible
135 for scalar assignments. We should probably have something
136 similar for aggregates, but right now removing that check just
137 breaks everything. */
138 gcc_checking_assert (TYPE_MAIN_VARIANT (t1
) == TYPE_MAIN_VARIANT (t2
)
139 || AGGREGATE_TYPE_P (TREE_TYPE (lhs
)));
141 tmp
= fold_build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
,
143 gfc_add_expr_to_block (pblock
, tmp
);
148 gfc_add_modify (stmtblock_t
* pblock
, tree lhs
, tree rhs
)
150 gfc_add_modify_loc (input_location
, pblock
, lhs
, rhs
);
154 /* Create a new scope/binding level and initialize a block. Care must be
155 taken when translating expressions as any temporaries will be placed in
156 the innermost scope. */
159 gfc_start_block (stmtblock_t
* block
)
161 /* Start a new binding level. */
163 block
->has_scope
= 1;
165 /* The block is empty. */
166 block
->head
= NULL_TREE
;
170 /* Initialize a block without creating a new scope. */
173 gfc_init_block (stmtblock_t
* block
)
175 block
->head
= NULL_TREE
;
176 block
->has_scope
= 0;
180 /* Sometimes we create a scope but it turns out that we don't actually
181 need it. This function merges the scope of BLOCK with its parent.
182 Only variable decls will be merged, you still need to add the code. */
185 gfc_merge_block_scope (stmtblock_t
* block
)
190 gcc_assert (block
->has_scope
);
191 block
->has_scope
= 0;
193 /* Remember the decls in this scope. */
197 /* Add them to the parent scope. */
198 while (decl
!= NULL_TREE
)
200 next
= DECL_CHAIN (decl
);
201 DECL_CHAIN (decl
) = NULL_TREE
;
209 /* Finish a scope containing a block of statements. */
212 gfc_finish_block (stmtblock_t
* stmtblock
)
218 expr
= stmtblock
->head
;
220 expr
= build_empty_stmt (input_location
);
222 stmtblock
->head
= NULL_TREE
;
224 if (stmtblock
->has_scope
)
230 block
= poplevel (1, 0);
231 expr
= build3_v (BIND_EXPR
, decl
, expr
, block
);
241 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
242 natural type is used. */
245 gfc_build_addr_expr (tree type
, tree t
)
247 tree base_type
= TREE_TYPE (t
);
250 if (type
&& POINTER_TYPE_P (type
)
251 && TREE_CODE (base_type
) == ARRAY_TYPE
252 && TYPE_MAIN_VARIANT (TREE_TYPE (type
))
253 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type
)))
255 tree min_val
= size_zero_node
;
256 tree type_domain
= TYPE_DOMAIN (base_type
);
257 if (type_domain
&& TYPE_MIN_VALUE (type_domain
))
258 min_val
= TYPE_MIN_VALUE (type_domain
);
259 t
= fold (build4_loc (input_location
, ARRAY_REF
, TREE_TYPE (type
),
260 t
, min_val
, NULL_TREE
, NULL_TREE
));
264 natural_type
= build_pointer_type (base_type
);
266 if (TREE_CODE (t
) == INDIRECT_REF
)
270 t
= TREE_OPERAND (t
, 0);
271 natural_type
= TREE_TYPE (t
);
275 tree base
= get_base_address (t
);
276 if (base
&& DECL_P (base
))
277 TREE_ADDRESSABLE (base
) = 1;
278 t
= fold_build1_loc (input_location
, ADDR_EXPR
, natural_type
, t
);
281 if (type
&& natural_type
!= type
)
282 t
= convert (type
, t
);
289 get_array_span (tree type
, tree decl
)
293 /* Return the span for deferred character length array references. */
294 if (type
&& TREE_CODE (type
) == ARRAY_TYPE
295 && TYPE_MAX_VALUE (TYPE_DOMAIN (type
)) != NULL_TREE
296 && (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type
)))
297 || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) == INDIRECT_REF
)
298 && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) == INDIRECT_REF
299 || TREE_CODE (decl
) == FUNCTION_DECL
300 || DECL_CONTEXT (TYPE_MAX_VALUE (TYPE_DOMAIN (type
)))
301 == DECL_CONTEXT (decl
)))
303 span
= fold_convert (gfc_array_index_type
,
304 TYPE_MAX_VALUE (TYPE_DOMAIN (type
)));
305 span
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
306 fold_convert (gfc_array_index_type
,
307 TYPE_SIZE_UNIT (TREE_TYPE (type
))),
310 else if (type
&& TREE_CODE (type
) == ARRAY_TYPE
311 && TYPE_MAX_VALUE (TYPE_DOMAIN (type
)) != NULL_TREE
312 && integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))))
314 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
)))
315 span
= gfc_conv_descriptor_span_get (decl
);
319 /* Likewise for class array or pointer array references. */
320 else if (TREE_CODE (decl
) == FIELD_DECL
321 || VAR_OR_FUNCTION_DECL_P (decl
)
322 || TREE_CODE (decl
) == PARM_DECL
)
324 if (GFC_DECL_CLASS (decl
))
326 /* When a temporary is in place for the class array, then the
327 original class' declaration is stored in the saved
329 if (DECL_LANG_SPECIFIC (decl
) && GFC_DECL_SAVED_DESCRIPTOR (decl
))
330 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
333 /* Allow for dummy arguments and other good things. */
334 if (POINTER_TYPE_P (TREE_TYPE (decl
)))
335 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
337 /* Check if '_data' is an array descriptor. If it is not,
338 the array must be one of the components of the class
339 object, so return a null span. */
340 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
341 gfc_class_data_get (decl
))))
344 span
= gfc_class_vtab_size_get (decl
);
346 else if (GFC_DECL_PTR_ARRAY_P (decl
))
348 if (TREE_CODE (decl
) == PARM_DECL
)
349 decl
= build_fold_indirect_ref_loc (input_location
, decl
);
350 span
= gfc_conv_descriptor_span_get (decl
);
362 /* Build an ARRAY_REF with its natural type. */
365 gfc_build_array_ref (tree base
, tree offset
, tree decl
, tree vptr
)
367 tree type
= TREE_TYPE (base
);
369 tree span
= NULL_TREE
;
371 if (GFC_ARRAY_TYPE_P (type
) && GFC_TYPE_ARRAY_RANK (type
) == 0)
373 gcc_assert (GFC_TYPE_ARRAY_CORANK (type
) > 0);
375 return fold_convert (TYPE_MAIN_VARIANT (type
), base
);
378 /* Scalar coarray, there is nothing to do. */
379 if (TREE_CODE (type
) != ARRAY_TYPE
)
381 gcc_assert (decl
== NULL_TREE
);
382 gcc_assert (integer_zerop (offset
));
386 type
= TREE_TYPE (type
);
389 TREE_ADDRESSABLE (base
) = 1;
391 /* Strip NON_LVALUE_EXPR nodes. */
392 STRIP_TYPE_NOPS (offset
);
394 /* If decl or vptr are non-null, pointer arithmetic for the array reference
395 is likely. Generate the 'span' for the array reference. */
397 span
= gfc_vptr_size_get (vptr
);
400 if (TREE_CODE (decl
) == COMPONENT_REF
)
401 span
= gfc_conv_descriptor_span_get (decl
);
403 span
= get_array_span (type
, decl
);
406 /* If a non-null span has been generated reference the element with
407 pointer arithmetic. */
408 if (span
!= NULL_TREE
)
410 offset
= fold_build2_loc (input_location
, MULT_EXPR
,
411 gfc_array_index_type
,
413 tmp
= gfc_build_addr_expr (pvoid_type_node
, base
);
414 tmp
= fold_build_pointer_plus_loc (input_location
, tmp
, offset
);
415 tmp
= fold_convert (build_pointer_type (type
), tmp
);
416 if (!TYPE_STRING_FLAG (type
))
417 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
420 /* Otherwise use a straightforward array reference. */
422 return build4_loc (input_location
, ARRAY_REF
, type
, base
, offset
,
423 NULL_TREE
, NULL_TREE
);
427 /* Generate a call to print a runtime error possibly including multiple
428 arguments and a locus. */
431 trans_runtime_error_vararg (bool error
, locus
* where
, const char* msgid
,
444 /* Compute the number of extra arguments from the format string. */
445 for (p
= msgid
, nargs
= 0; *p
; p
++)
453 /* The code to generate the error. */
454 gfc_start_block (&block
);
458 line
= LOCATION_LINE (where
->lb
->location
);
459 message
= xasprintf ("At line %d of file %s", line
,
460 where
->lb
->file
->filename
);
463 message
= xasprintf ("In file '%s', around line %d",
464 gfc_source_file
, LOCATION_LINE (input_location
) + 1);
466 arg
= gfc_build_addr_expr (pchar_type_node
,
467 gfc_build_localized_cstring_const (message
));
470 message
= xasprintf ("%s", _(msgid
));
471 arg2
= gfc_build_addr_expr (pchar_type_node
,
472 gfc_build_localized_cstring_const (message
));
475 /* Build the argument array. */
476 argarray
= XALLOCAVEC (tree
, nargs
+ 2);
479 for (i
= 0; i
< nargs
; i
++)
480 argarray
[2 + i
] = va_arg (ap
, tree
);
482 /* Build the function call to runtime_(warning,error)_at; because of the
483 variable number of arguments, we can't use build_call_expr_loc dinput_location,
486 fntype
= TREE_TYPE (gfor_fndecl_runtime_error_at
);
488 fntype
= TREE_TYPE (gfor_fndecl_runtime_warning_at
);
490 loc
= where
? where
->lb
->location
: input_location
;
491 tmp
= fold_build_call_array_loc (loc
, TREE_TYPE (fntype
),
492 fold_build1_loc (loc
, ADDR_EXPR
,
493 build_pointer_type (fntype
),
495 ? gfor_fndecl_runtime_error_at
496 : gfor_fndecl_runtime_warning_at
),
497 nargs
+ 2, argarray
);
498 gfc_add_expr_to_block (&block
, tmp
);
500 return gfc_finish_block (&block
);
505 gfc_trans_runtime_error (bool error
, locus
* where
, const char* msgid
, ...)
510 va_start (ap
, msgid
);
511 result
= trans_runtime_error_vararg (error
, where
, msgid
, ap
);
517 /* Generate a runtime error if COND is true. */
520 gfc_trans_runtime_check (bool error
, bool once
, tree cond
, stmtblock_t
* pblock
,
521 locus
* where
, const char * msgid
, ...)
529 if (integer_zerop (cond
))
534 tmpvar
= gfc_create_var (logical_type_node
, "print_warning");
535 TREE_STATIC (tmpvar
) = 1;
536 DECL_INITIAL (tmpvar
) = logical_true_node
;
537 gfc_add_expr_to_block (pblock
, tmpvar
);
540 gfc_start_block (&block
);
542 /* For error, runtime_error_at already implies PRED_NORETURN. */
544 gfc_add_expr_to_block (&block
, build_predict_expr (PRED_FORTRAN_WARN_ONCE
,
547 /* The code to generate the error. */
548 va_start (ap
, msgid
);
549 gfc_add_expr_to_block (&block
,
550 trans_runtime_error_vararg (error
, where
,
555 gfc_add_modify (&block
, tmpvar
, logical_false_node
);
557 body
= gfc_finish_block (&block
);
559 if (integer_onep (cond
))
561 gfc_add_expr_to_block (pblock
, body
);
566 cond
= fold_build2_loc (where
->lb
->location
, TRUTH_AND_EXPR
,
567 long_integer_type_node
, tmpvar
, cond
);
569 cond
= fold_convert (long_integer_type_node
, cond
);
571 tmp
= fold_build3_loc (where
->lb
->location
, COND_EXPR
, void_type_node
,
573 build_empty_stmt (where
->lb
->location
));
574 gfc_add_expr_to_block (pblock
, tmp
);
579 /* Call malloc to allocate size bytes of memory, with special conditions:
580 + if size == 0, return a malloced area of size 1,
581 + if malloc returns NULL, issue a runtime error. */
583 gfc_call_malloc (stmtblock_t
* block
, tree type
, tree size
)
585 tree tmp
, msg
, malloc_result
, null_result
, res
, malloc_tree
;
588 /* Create a variable to hold the result. */
589 res
= gfc_create_var (prvoid_type_node
, NULL
);
592 gfc_start_block (&block2
);
594 size
= fold_convert (size_type_node
, size
);
595 size
= fold_build2_loc (input_location
, MAX_EXPR
, size_type_node
, size
,
596 build_int_cst (size_type_node
, 1));
598 malloc_tree
= builtin_decl_explicit (BUILT_IN_MALLOC
);
599 gfc_add_modify (&block2
, res
,
600 fold_convert (prvoid_type_node
,
601 build_call_expr_loc (input_location
,
602 malloc_tree
, 1, size
)));
604 /* Optionally check whether malloc was successful. */
605 if (gfc_option
.rtcheck
& GFC_RTCHECK_MEM
)
607 null_result
= fold_build2_loc (input_location
, EQ_EXPR
,
608 logical_type_node
, res
,
609 build_int_cst (pvoid_type_node
, 0));
610 msg
= gfc_build_addr_expr (pchar_type_node
,
611 gfc_build_localized_cstring_const ("Memory allocation failed"));
612 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
614 build_call_expr_loc (input_location
,
615 gfor_fndecl_os_error
, 1, msg
),
616 build_empty_stmt (input_location
));
617 gfc_add_expr_to_block (&block2
, tmp
);
620 malloc_result
= gfc_finish_block (&block2
);
621 gfc_add_expr_to_block (block
, malloc_result
);
624 res
= fold_convert (type
, res
);
629 /* Allocate memory, using an optional status argument.
631 This function follows the following pseudo-code:
634 allocate (size_t size, integer_type stat)
641 newmem = malloc (MAX (size, 1));
645 *stat = LIBERROR_ALLOCATION;
647 runtime_error ("Allocation would exceed memory limit");
652 gfc_allocate_using_malloc (stmtblock_t
* block
, tree pointer
,
653 tree size
, tree status
)
655 tree tmp
, error_cond
;
656 stmtblock_t on_error
;
657 tree status_type
= status
? TREE_TYPE (status
) : NULL_TREE
;
659 /* If successful and stat= is given, set status to 0. */
660 if (status
!= NULL_TREE
)
661 gfc_add_expr_to_block (block
,
662 fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
663 status
, build_int_cst (status_type
, 0)));
665 /* The allocation itself. */
666 size
= fold_convert (size_type_node
, size
);
667 gfc_add_modify (block
, pointer
,
668 fold_convert (TREE_TYPE (pointer
),
669 build_call_expr_loc (input_location
,
670 builtin_decl_explicit (BUILT_IN_MALLOC
), 1,
671 fold_build2_loc (input_location
,
672 MAX_EXPR
, size_type_node
, size
,
673 build_int_cst (size_type_node
, 1)))));
675 /* What to do in case of error. */
676 gfc_start_block (&on_error
);
677 if (status
!= NULL_TREE
)
679 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
, status
,
680 build_int_cst (status_type
, LIBERROR_ALLOCATION
));
681 gfc_add_expr_to_block (&on_error
, tmp
);
685 /* Here, os_error already implies PRED_NORETURN. */
686 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_os_error
, 1,
687 gfc_build_addr_expr (pchar_type_node
,
688 gfc_build_localized_cstring_const
689 ("Allocation would exceed memory limit")));
690 gfc_add_expr_to_block (&on_error
, tmp
);
693 error_cond
= fold_build2_loc (input_location
, EQ_EXPR
,
694 logical_type_node
, pointer
,
695 build_int_cst (prvoid_type_node
, 0));
696 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
697 gfc_unlikely (error_cond
, PRED_FORTRAN_FAIL_ALLOC
),
698 gfc_finish_block (&on_error
),
699 build_empty_stmt (input_location
));
701 gfc_add_expr_to_block (block
, tmp
);
705 /* Allocate memory, using an optional status argument.
707 This function follows the following pseudo-code:
710 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
714 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
718 gfc_allocate_using_caf_lib (stmtblock_t
* block
, tree pointer
, tree size
,
719 tree token
, tree status
, tree errmsg
, tree errlen
,
720 gfc_coarray_regtype alloc_type
)
724 gcc_assert (token
!= NULL_TREE
);
726 /* The allocation itself. */
727 if (status
== NULL_TREE
)
728 pstat
= null_pointer_node
;
730 pstat
= gfc_build_addr_expr (NULL_TREE
, status
);
732 if (errmsg
== NULL_TREE
)
734 gcc_assert(errlen
== NULL_TREE
);
735 errmsg
= null_pointer_node
;
736 errlen
= build_int_cst (integer_type_node
, 0);
739 size
= fold_convert (size_type_node
, size
);
740 tmp
= build_call_expr_loc (input_location
,
741 gfor_fndecl_caf_register
, 7,
742 fold_build2_loc (input_location
,
743 MAX_EXPR
, size_type_node
, size
, size_one_node
),
744 build_int_cst (integer_type_node
, alloc_type
),
745 token
, gfc_build_addr_expr (pvoid_type_node
, pointer
),
746 pstat
, errmsg
, errlen
);
748 gfc_add_expr_to_block (block
, tmp
);
750 /* It guarantees memory consistency within the same segment */
751 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory"),
752 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
753 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
754 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
755 ASM_VOLATILE_P (tmp
) = 1;
756 gfc_add_expr_to_block (block
, tmp
);
760 /* Generate code for an ALLOCATE statement when the argument is an
761 allocatable variable. If the variable is currently allocated, it is an
762 error to allocate it again.
764 This function follows the following pseudo-code:
767 allocate_allocatable (void *mem, size_t size, integer_type stat)
770 return allocate (size, stat);
774 stat = LIBERROR_ALLOCATION;
776 runtime_error ("Attempting to allocate already allocated variable");
780 expr must be set to the original expression being allocated for its locus
781 and variable name in case a runtime error has to be printed. */
783 gfc_allocate_allocatable (stmtblock_t
* block
, tree mem
, tree size
,
784 tree token
, tree status
, tree errmsg
, tree errlen
,
785 tree label_finish
, gfc_expr
* expr
, int corank
)
787 stmtblock_t alloc_block
;
788 tree tmp
, null_mem
, alloc
, error
;
789 tree type
= TREE_TYPE (mem
);
790 symbol_attribute caf_attr
;
791 bool need_assign
= false, refs_comp
= false;
792 gfc_coarray_regtype caf_alloc_type
= GFC_CAF_COARRAY_ALLOC
;
794 size
= fold_convert (size_type_node
, size
);
795 null_mem
= gfc_unlikely (fold_build2_loc (input_location
, NE_EXPR
,
796 logical_type_node
, mem
,
797 build_int_cst (type
, 0)),
798 PRED_FORTRAN_REALLOC
);
800 /* If mem is NULL, we call gfc_allocate_using_malloc or
801 gfc_allocate_using_lib. */
802 gfc_start_block (&alloc_block
);
804 if (flag_coarray
== GFC_FCOARRAY_LIB
)
805 caf_attr
= gfc_caf_attr (expr
, true, &refs_comp
);
807 if (flag_coarray
== GFC_FCOARRAY_LIB
808 && (corank
> 0 || caf_attr
.codimension
))
810 tree cond
, sub_caf_tree
;
812 bool compute_special_caf_types_size
= false;
814 if (expr
->ts
.type
== BT_DERIVED
815 && expr
->ts
.u
.derived
->from_intmod
== INTMOD_ISO_FORTRAN_ENV
816 && expr
->ts
.u
.derived
->intmod_sym_id
== ISOFORTRAN_LOCK_TYPE
)
818 compute_special_caf_types_size
= true;
819 caf_alloc_type
= GFC_CAF_LOCK_ALLOC
;
821 else if (expr
->ts
.type
== BT_DERIVED
822 && expr
->ts
.u
.derived
->from_intmod
== INTMOD_ISO_FORTRAN_ENV
823 && expr
->ts
.u
.derived
->intmod_sym_id
== ISOFORTRAN_EVENT_TYPE
)
825 compute_special_caf_types_size
= true;
826 caf_alloc_type
= GFC_CAF_EVENT_ALLOC
;
828 else if (!caf_attr
.coarray_comp
&& refs_comp
)
829 /* Only allocatable components in a derived type coarray can be
831 caf_alloc_type
= GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY
;
833 gfc_init_se (&se
, NULL
);
834 sub_caf_tree
= gfc_get_ultimate_alloc_ptr_comps_caf_token (&se
, expr
);
835 if (sub_caf_tree
== NULL_TREE
)
836 sub_caf_tree
= token
;
838 /* When mem is an array ref, then strip the .data-ref. */
839 if (TREE_CODE (mem
) == COMPONENT_REF
840 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem
))))
841 tmp
= TREE_OPERAND (mem
, 0);
845 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp
))
846 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp
))->corank
== 0)
847 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp
)))
849 symbol_attribute attr
;
851 gfc_clear_attr (&attr
);
852 tmp
= gfc_conv_scalar_to_descriptor (&se
, mem
, attr
);
855 gfc_add_block_to_block (&alloc_block
, &se
.pre
);
857 /* In the front end, we represent the lock variable as pointer. However,
858 the FE only passes the pointer around and leaves the actual
859 representation to the library. Hence, we have to convert back to the
860 number of elements. */
861 if (compute_special_caf_types_size
)
862 size
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
, size_type_node
,
863 size
, TYPE_SIZE_UNIT (ptr_type_node
));
865 gfc_allocate_using_caf_lib (&alloc_block
, tmp
, size
, sub_caf_tree
,
866 status
, errmsg
, errlen
, caf_alloc_type
);
868 gfc_add_modify (&alloc_block
, mem
, fold_convert (TREE_TYPE (mem
),
869 gfc_conv_descriptor_data_get (tmp
)));
870 if (status
!= NULL_TREE
)
872 TREE_USED (label_finish
) = 1;
873 tmp
= build1_v (GOTO_EXPR
, label_finish
);
874 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
875 status
, build_zero_cst (TREE_TYPE (status
)));
876 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
877 gfc_unlikely (cond
, PRED_FORTRAN_FAIL_ALLOC
),
878 tmp
, build_empty_stmt (input_location
));
879 gfc_add_expr_to_block (&alloc_block
, tmp
);
883 gfc_allocate_using_malloc (&alloc_block
, mem
, size
, status
);
885 alloc
= gfc_finish_block (&alloc_block
);
887 /* If mem is not NULL, we issue a runtime error or set the
893 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
894 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
895 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
897 error
= gfc_trans_runtime_error (true, &expr
->where
,
898 "Attempting to allocate already"
899 " allocated variable '%s'",
903 error
= gfc_trans_runtime_error (true, NULL
,
904 "Attempting to allocate already allocated"
907 if (status
!= NULL_TREE
)
909 tree status_type
= TREE_TYPE (status
);
911 error
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
912 status
, build_int_cst (status_type
, LIBERROR_ALLOCATION
));
915 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, null_mem
,
917 gfc_add_expr_to_block (block
, tmp
);
921 /* Free a given variable. */
924 gfc_call_free (tree var
)
926 return build_call_expr_loc (input_location
,
927 builtin_decl_explicit (BUILT_IN_FREE
),
928 1, fold_convert (pvoid_type_node
, var
));
932 /* Build a call to a FINAL procedure, which finalizes "var". */
935 gfc_build_final_call (gfc_typespec ts
, gfc_expr
*final_wrapper
, gfc_expr
*var
,
936 bool fini_coarray
, gfc_expr
*class_size
)
940 tree final_fndecl
, array
, size
, tmp
;
941 symbol_attribute attr
;
943 gcc_assert (final_wrapper
->expr_type
== EXPR_VARIABLE
);
946 gfc_start_block (&block
);
947 gfc_init_se (&se
, NULL
);
948 gfc_conv_expr (&se
, final_wrapper
);
949 final_fndecl
= se
.expr
;
950 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl
)))
951 final_fndecl
= build_fold_indirect_ref_loc (input_location
, final_fndecl
);
953 if (ts
.type
== BT_DERIVED
)
957 gcc_assert (!class_size
);
958 elem_size
= gfc_typenode_for_spec (&ts
);
959 elem_size
= TYPE_SIZE_UNIT (elem_size
);
960 size
= fold_convert (gfc_array_index_type
, elem_size
);
962 gfc_init_se (&se
, NULL
);
966 se
.descriptor_only
= 1;
967 gfc_conv_expr_descriptor (&se
, var
);
972 gfc_conv_expr (&se
, var
);
973 gcc_assert (se
.pre
.head
== NULL_TREE
&& se
.post
.head
== NULL_TREE
);
976 /* No copy back needed, hence set attr's allocatable/pointer
978 gfc_clear_attr (&attr
);
979 gfc_init_se (&se
, NULL
);
980 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
981 gcc_assert (se
.post
.head
== NULL_TREE
);
986 gfc_expr
*array_expr
;
987 gcc_assert (class_size
);
988 gfc_init_se (&se
, NULL
);
989 gfc_conv_expr (&se
, class_size
);
990 gfc_add_block_to_block (&block
, &se
.pre
);
991 gcc_assert (se
.post
.head
== NULL_TREE
);
994 array_expr
= gfc_copy_expr (var
);
995 gfc_init_se (&se
, NULL
);
997 if (array_expr
->rank
)
999 gfc_add_class_array_ref (array_expr
);
1000 se
.descriptor_only
= 1;
1001 gfc_conv_expr_descriptor (&se
, array_expr
);
1006 gfc_add_data_component (array_expr
);
1007 gfc_conv_expr (&se
, array_expr
);
1008 gfc_add_block_to_block (&block
, &se
.pre
);
1009 gcc_assert (se
.post
.head
== NULL_TREE
);
1011 if (TREE_CODE (array
) == ADDR_EXPR
1012 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array
, 0))))
1013 tmp
= TREE_OPERAND (array
, 0);
1015 if (!gfc_is_coarray (array_expr
))
1017 /* No copy back needed, hence set attr's allocatable/pointer
1019 gfc_clear_attr (&attr
);
1020 gfc_init_se (&se
, NULL
);
1021 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
1023 gcc_assert (se
.post
.head
== NULL_TREE
);
1025 gfc_free_expr (array_expr
);
1028 if (!POINTER_TYPE_P (TREE_TYPE (array
)))
1029 array
= gfc_build_addr_expr (NULL
, array
);
1031 gfc_add_block_to_block (&block
, &se
.pre
);
1032 tmp
= build_call_expr_loc (input_location
,
1033 final_fndecl
, 3, array
,
1034 size
, fini_coarray
? boolean_true_node
1035 : boolean_false_node
);
1036 gfc_add_block_to_block (&block
, &se
.post
);
1037 gfc_add_expr_to_block (&block
, tmp
);
1038 return gfc_finish_block (&block
);
1043 gfc_add_comp_finalizer_call (stmtblock_t
*block
, tree decl
, gfc_component
*comp
,
1048 tree final_fndecl
, size
, array
, tmp
, cond
;
1049 symbol_attribute attr
;
1050 gfc_expr
*final_expr
= NULL
;
1052 if (comp
->ts
.type
!= BT_DERIVED
&& comp
->ts
.type
!= BT_CLASS
)
1055 gfc_init_block (&block2
);
1057 if (comp
->ts
.type
== BT_DERIVED
)
1059 if (comp
->attr
.pointer
)
1062 gfc_is_finalizable (comp
->ts
.u
.derived
, &final_expr
);
1066 gfc_init_se (&se
, NULL
);
1067 gfc_conv_expr (&se
, final_expr
);
1068 final_fndecl
= se
.expr
;
1069 size
= gfc_typenode_for_spec (&comp
->ts
);
1070 size
= TYPE_SIZE_UNIT (size
);
1071 size
= fold_convert (gfc_array_index_type
, size
);
1075 else /* comp->ts.type == BT_CLASS. */
1077 if (CLASS_DATA (comp
)->attr
.class_pointer
)
1080 gfc_is_finalizable (CLASS_DATA (comp
)->ts
.u
.derived
, &final_expr
);
1081 final_fndecl
= gfc_class_vtab_final_get (decl
);
1082 size
= gfc_class_vtab_size_get (decl
);
1083 array
= gfc_class_data_get (decl
);
1086 if (comp
->attr
.allocatable
1087 || (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)->attr
.allocatable
))
1089 tmp
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array
))
1090 ? gfc_conv_descriptor_data_get (array
) : array
;
1091 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1092 tmp
, fold_convert (TREE_TYPE (tmp
),
1093 null_pointer_node
));
1096 cond
= logical_true_node
;
1098 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array
)))
1100 gfc_clear_attr (&attr
);
1101 gfc_init_se (&se
, NULL
);
1102 array
= gfc_conv_scalar_to_descriptor (&se
, array
, attr
);
1103 gfc_add_block_to_block (&block2
, &se
.pre
);
1104 gcc_assert (se
.post
.head
== NULL_TREE
);
1107 if (!POINTER_TYPE_P (TREE_TYPE (array
)))
1108 array
= gfc_build_addr_expr (NULL
, array
);
1112 tmp
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1114 fold_convert (TREE_TYPE (final_fndecl
),
1115 null_pointer_node
));
1116 cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
1117 logical_type_node
, cond
, tmp
);
1120 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl
)))
1121 final_fndecl
= build_fold_indirect_ref_loc (input_location
, final_fndecl
);
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_expr_to_block (&block2
, tmp
);
1128 tmp
= gfc_finish_block (&block2
);
1130 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
, tmp
,
1131 build_empty_stmt (input_location
));
1132 gfc_add_expr_to_block (block
, tmp
);
1138 /* Add a call to the finalizer, using the passed *expr. Returns
1139 true when a finalizer call has been inserted. */
1142 gfc_add_finalizer_call (stmtblock_t
*block
, gfc_expr
*expr2
)
1147 gfc_expr
*final_expr
= NULL
;
1148 gfc_expr
*elem_size
= NULL
;
1149 bool has_finalizer
= false;
1151 if (!expr2
|| (expr2
->ts
.type
!= BT_DERIVED
&& expr2
->ts
.type
!= BT_CLASS
))
1154 if (expr2
->ts
.type
== BT_DERIVED
)
1156 gfc_is_finalizable (expr2
->ts
.u
.derived
, &final_expr
);
1161 /* If we have a class array, we need go back to the class
1163 expr
= gfc_copy_expr (expr2
);
1165 if (expr
->ref
&& expr
->ref
->next
&& !expr
->ref
->next
->next
1166 && expr
->ref
->next
->type
== REF_ARRAY
1167 && expr
->ref
->type
== REF_COMPONENT
1168 && strcmp (expr
->ref
->u
.c
.component
->name
, "_data") == 0)
1170 gfc_free_ref_list (expr
->ref
);
1174 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
1175 if (ref
->next
&& ref
->next
->next
&& !ref
->next
->next
->next
1176 && ref
->next
->next
->type
== REF_ARRAY
1177 && ref
->next
->type
== REF_COMPONENT
1178 && strcmp (ref
->next
->u
.c
.component
->name
, "_data") == 0)
1180 gfc_free_ref_list (ref
->next
);
1184 if (expr
->ts
.type
== BT_CLASS
)
1186 has_finalizer
= gfc_is_finalizable (expr
->ts
.u
.derived
, NULL
);
1188 if (!expr2
->rank
&& !expr2
->ref
&& CLASS_DATA (expr2
->symtree
->n
.sym
)->as
)
1189 expr
->rank
= CLASS_DATA (expr2
->symtree
->n
.sym
)->as
->rank
;
1191 final_expr
= gfc_copy_expr (expr
);
1192 gfc_add_vptr_component (final_expr
);
1193 gfc_add_final_component (final_expr
);
1195 elem_size
= gfc_copy_expr (expr
);
1196 gfc_add_vptr_component (elem_size
);
1197 gfc_add_size_component (elem_size
);
1200 gcc_assert (final_expr
->expr_type
== EXPR_VARIABLE
);
1202 tmp
= gfc_build_final_call (expr
->ts
, final_expr
, expr
,
1205 if (expr
->ts
.type
== BT_CLASS
&& !has_finalizer
)
1210 gfc_init_se (&se
, NULL
);
1211 se
.want_pointer
= 1;
1212 gfc_conv_expr (&se
, final_expr
);
1213 cond
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1214 se
.expr
, build_int_cst (TREE_TYPE (se
.expr
), 0));
1216 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1217 but already sym->_vtab itself. */
1218 if (UNLIMITED_POLY (expr
))
1221 gfc_expr
*vptr_expr
;
1223 vptr_expr
= gfc_copy_expr (expr
);
1224 gfc_add_vptr_component (vptr_expr
);
1226 gfc_init_se (&se
, NULL
);
1227 se
.want_pointer
= 1;
1228 gfc_conv_expr (&se
, vptr_expr
);
1229 gfc_free_expr (vptr_expr
);
1231 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1233 build_int_cst (TREE_TYPE (se
.expr
), 0));
1234 cond
= fold_build2_loc (input_location
, TRUTH_ANDIF_EXPR
,
1235 logical_type_node
, cond2
, cond
);
1238 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1239 cond
, tmp
, build_empty_stmt (input_location
));
1242 gfc_add_expr_to_block (block
, tmp
);
1248 /* User-deallocate; we emit the code directly from the front-end, and the
1249 logic is the same as the previous library function:
1252 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1259 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1269 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1270 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1271 even when no status variable is passed to us (this is used for
1272 unconditional deallocation generated by the front-end at end of
1275 If a runtime-message is possible, `expr' must point to the original
1276 expression being deallocated for its locus and variable name.
1278 For coarrays, "pointer" must be the array descriptor and not its
1281 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1282 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1283 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1286 gfc_deallocate_with_status (tree pointer
, tree status
, tree errmsg
,
1287 tree errlen
, tree label_finish
,
1288 bool can_fail
, gfc_expr
* expr
,
1289 int coarray_dealloc_mode
, tree add_when_allocated
,
1292 stmtblock_t null
, non_null
;
1293 tree cond
, tmp
, error
;
1294 tree status_type
= NULL_TREE
;
1295 tree token
= NULL_TREE
;
1296 gfc_coarray_deregtype caf_dereg_type
= GFC_CAF_COARRAY_DEREGISTER
;
1298 if (coarray_dealloc_mode
>= GFC_CAF_COARRAY_ANALYZE
)
1300 if (flag_coarray
== GFC_FCOARRAY_LIB
)
1306 tree caf_type
, caf_decl
= pointer
;
1307 pointer
= gfc_conv_descriptor_data_get (caf_decl
);
1308 caf_type
= TREE_TYPE (caf_decl
);
1309 STRIP_NOPS (pointer
);
1310 if (GFC_DESCRIPTOR_TYPE_P (caf_type
))
1311 token
= gfc_conv_descriptor_token (caf_decl
);
1312 else if (DECL_LANG_SPECIFIC (caf_decl
)
1313 && GFC_DECL_TOKEN (caf_decl
) != NULL_TREE
)
1314 token
= GFC_DECL_TOKEN (caf_decl
);
1317 gcc_assert (GFC_ARRAY_TYPE_P (caf_type
)
1318 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
)
1320 token
= GFC_TYPE_ARRAY_CAF_TOKEN (caf_type
);
1324 if (coarray_dealloc_mode
== GFC_CAF_COARRAY_ANALYZE
)
1327 if (expr
&& !gfc_caf_attr (expr
, false, &comp_ref
).coarray_comp
1329 caf_dereg_type
= GFC_CAF_COARRAY_DEALLOCATE_ONLY
;
1330 // else do a deregister as set by default.
1333 caf_dereg_type
= (enum gfc_coarray_deregtype
) coarray_dealloc_mode
;
1335 else if (flag_coarray
== GFC_FCOARRAY_SINGLE
)
1336 pointer
= gfc_conv_descriptor_data_get (pointer
);
1338 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer
)))
1339 pointer
= gfc_conv_descriptor_data_get (pointer
);
1341 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
, pointer
,
1342 build_int_cst (TREE_TYPE (pointer
), 0));
1344 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1345 we emit a runtime error. */
1346 gfc_start_block (&null
);
1351 gcc_assert (expr
&& expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
1353 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
1354 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
1356 error
= gfc_trans_runtime_error (true, &expr
->where
,
1357 "Attempt to DEALLOCATE unallocated '%s'",
1361 error
= build_empty_stmt (input_location
);
1363 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1367 status_type
= TREE_TYPE (TREE_TYPE (status
));
1368 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1369 status
, build_int_cst (TREE_TYPE (status
), 0));
1370 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1371 fold_build1_loc (input_location
, INDIRECT_REF
,
1372 status_type
, status
),
1373 build_int_cst (status_type
, 1));
1374 error
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1378 gfc_add_expr_to_block (&null
, error
);
1380 /* When POINTER is not NULL, we free it. */
1381 gfc_start_block (&non_null
);
1382 if (add_when_allocated
)
1383 gfc_add_expr_to_block (&non_null
, add_when_allocated
);
1384 gfc_add_finalizer_call (&non_null
, expr
);
1385 if (coarray_dealloc_mode
== GFC_CAF_COARRAY_NOCOARRAY
1386 || flag_coarray
!= GFC_FCOARRAY_LIB
)
1388 tmp
= build_call_expr_loc (input_location
,
1389 builtin_decl_explicit (BUILT_IN_FREE
), 1,
1390 fold_convert (pvoid_type_node
, pointer
));
1391 gfc_add_expr_to_block (&non_null
, tmp
);
1392 gfc_add_modify (&non_null
, pointer
, build_int_cst (TREE_TYPE (pointer
),
1395 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1397 /* We set STATUS to zero if it is present. */
1398 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1401 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1403 build_int_cst (TREE_TYPE (status
), 0));
1404 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1405 fold_build1_loc (input_location
, INDIRECT_REF
,
1406 status_type
, status
),
1407 build_int_cst (status_type
, 0));
1408 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1409 gfc_unlikely (cond2
, PRED_FORTRAN_FAIL_ALLOC
),
1410 tmp
, build_empty_stmt (input_location
));
1411 gfc_add_expr_to_block (&non_null
, tmp
);
1416 tree cond2
, pstat
= null_pointer_node
;
1418 if (errmsg
== NULL_TREE
)
1420 gcc_assert (errlen
== NULL_TREE
);
1421 errmsg
= null_pointer_node
;
1422 errlen
= build_zero_cst (integer_type_node
);
1426 gcc_assert (errlen
!= NULL_TREE
);
1427 if (!POINTER_TYPE_P (TREE_TYPE (errmsg
)))
1428 errmsg
= gfc_build_addr_expr (NULL_TREE
, errmsg
);
1431 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1433 gcc_assert (status_type
== integer_type_node
);
1437 token
= gfc_build_addr_expr (NULL_TREE
, token
);
1438 gcc_assert (caf_dereg_type
> GFC_CAF_COARRAY_ANALYZE
);
1439 tmp
= build_call_expr_loc (input_location
,
1440 gfor_fndecl_caf_deregister
, 5,
1441 token
, build_int_cst (integer_type_node
,
1443 pstat
, errmsg
, errlen
);
1444 gfc_add_expr_to_block (&non_null
, tmp
);
1446 /* It guarantees memory consistency within the same segment */
1447 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory"),
1448 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
1449 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
1450 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
1451 ASM_VOLATILE_P (tmp
) = 1;
1452 gfc_add_expr_to_block (&non_null
, tmp
);
1454 if (status
!= NULL_TREE
)
1456 tree stat
= build_fold_indirect_ref_loc (input_location
, status
);
1457 tree nullify
= fold_build2_loc (input_location
, MODIFY_EXPR
,
1458 void_type_node
, pointer
,
1459 build_int_cst (TREE_TYPE (pointer
),
1462 TREE_USED (label_finish
) = 1;
1463 tmp
= build1_v (GOTO_EXPR
, label_finish
);
1464 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1465 stat
, build_zero_cst (TREE_TYPE (stat
)));
1466 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1467 gfc_unlikely (cond2
, PRED_FORTRAN_REALLOC
),
1469 gfc_add_expr_to_block (&non_null
, tmp
);
1472 gfc_add_modify (&non_null
, pointer
, build_int_cst (TREE_TYPE (pointer
),
1476 return fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
1477 gfc_finish_block (&null
),
1478 gfc_finish_block (&non_null
));
1482 /* Generate code for deallocation of allocatable scalars (variables or
1483 components). Before the object itself is freed, any allocatable
1484 subcomponents are being deallocated. */
1487 gfc_deallocate_scalar_with_status (tree pointer
, tree status
, tree label_finish
,
1488 bool can_fail
, gfc_expr
* expr
,
1489 gfc_typespec ts
, bool coarray
)
1491 stmtblock_t null
, non_null
;
1492 tree cond
, tmp
, error
;
1493 bool finalizable
, comp_ref
;
1494 gfc_coarray_deregtype caf_dereg_type
= GFC_CAF_COARRAY_DEREGISTER
;
1496 if (coarray
&& expr
&& !gfc_caf_attr (expr
, false, &comp_ref
).coarray_comp
1498 caf_dereg_type
= GFC_CAF_COARRAY_DEALLOCATE_ONLY
;
1500 cond
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
, pointer
,
1501 build_int_cst (TREE_TYPE (pointer
), 0));
1503 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1504 we emit a runtime error. */
1505 gfc_start_block (&null
);
1510 gcc_assert (expr
&& expr
->expr_type
== EXPR_VARIABLE
&& expr
->symtree
);
1512 varname
= gfc_build_cstring_const (expr
->symtree
->name
);
1513 varname
= gfc_build_addr_expr (pchar_type_node
, varname
);
1515 error
= gfc_trans_runtime_error (true, &expr
->where
,
1516 "Attempt to DEALLOCATE unallocated '%s'",
1520 error
= build_empty_stmt (input_location
);
1522 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1524 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1527 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1528 status
, build_int_cst (TREE_TYPE (status
), 0));
1529 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1530 fold_build1_loc (input_location
, INDIRECT_REF
,
1531 status_type
, status
),
1532 build_int_cst (status_type
, 1));
1533 error
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1536 gfc_add_expr_to_block (&null
, error
);
1538 /* When POINTER is not NULL, we free it. */
1539 gfc_start_block (&non_null
);
1541 /* Free allocatable components. */
1542 finalizable
= gfc_add_finalizer_call (&non_null
, expr
);
1543 if (!finalizable
&& ts
.type
== BT_DERIVED
&& ts
.u
.derived
->attr
.alloc_comp
)
1545 int caf_mode
= coarray
1546 ? ((caf_dereg_type
== GFC_CAF_COARRAY_DEALLOCATE_ONLY
1547 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY
: 0)
1548 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1549 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY
)
1551 if (coarray
&& GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer
)))
1552 tmp
= gfc_conv_descriptor_data_get (pointer
);
1554 tmp
= build_fold_indirect_ref_loc (input_location
, pointer
);
1555 tmp
= gfc_deallocate_alloc_comp (ts
.u
.derived
, tmp
, 0, caf_mode
);
1556 gfc_add_expr_to_block (&non_null
, tmp
);
1559 if (!coarray
|| flag_coarray
== GFC_FCOARRAY_SINGLE
)
1561 tmp
= build_call_expr_loc (input_location
,
1562 builtin_decl_explicit (BUILT_IN_FREE
), 1,
1563 fold_convert (pvoid_type_node
, pointer
));
1564 gfc_add_expr_to_block (&non_null
, tmp
);
1566 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1568 /* We set STATUS to zero if it is present. */
1569 tree status_type
= TREE_TYPE (TREE_TYPE (status
));
1572 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1574 build_int_cst (TREE_TYPE (status
), 0));
1575 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, status_type
,
1576 fold_build1_loc (input_location
, INDIRECT_REF
,
1577 status_type
, status
),
1578 build_int_cst (status_type
, 0));
1579 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1580 cond2
, tmp
, build_empty_stmt (input_location
));
1581 gfc_add_expr_to_block (&non_null
, tmp
);
1587 tree pstat
= null_pointer_node
;
1590 gfc_init_se (&se
, NULL
);
1591 token
= gfc_get_ultimate_alloc_ptr_comps_caf_token (&se
, expr
);
1592 gcc_assert (token
!= NULL_TREE
);
1594 if (status
!= NULL_TREE
&& !integer_zerop (status
))
1596 gcc_assert (TREE_TYPE (TREE_TYPE (status
)) == integer_type_node
);
1600 tmp
= build_call_expr_loc (input_location
,
1601 gfor_fndecl_caf_deregister
, 5,
1602 token
, build_int_cst (integer_type_node
,
1604 pstat
, null_pointer_node
, integer_zero_node
);
1605 gfc_add_expr_to_block (&non_null
, tmp
);
1607 /* It guarantees memory consistency within the same segment. */
1608 tmp
= gfc_build_string_const (strlen ("memory")+1, "memory");
1609 tmp
= build5_loc (input_location
, ASM_EXPR
, void_type_node
,
1610 gfc_build_string_const (1, ""), NULL_TREE
, NULL_TREE
,
1611 tree_cons (NULL_TREE
, tmp
, NULL_TREE
), NULL_TREE
);
1612 ASM_VOLATILE_P (tmp
) = 1;
1613 gfc_add_expr_to_block (&non_null
, tmp
);
1615 if (status
!= NULL_TREE
)
1617 tree stat
= build_fold_indirect_ref_loc (input_location
, status
);
1620 TREE_USED (label_finish
) = 1;
1621 tmp
= build1_v (GOTO_EXPR
, label_finish
);
1622 cond2
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
,
1623 stat
, build_zero_cst (TREE_TYPE (stat
)));
1624 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1625 gfc_unlikely (cond2
, PRED_FORTRAN_REALLOC
),
1626 tmp
, build_empty_stmt (input_location
));
1627 gfc_add_expr_to_block (&non_null
, tmp
);
1631 return fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
,
1632 gfc_finish_block (&null
),
1633 gfc_finish_block (&non_null
));
1636 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1637 following pseudo-code:
1640 internal_realloc (void *mem, size_t size)
1642 res = realloc (mem, size);
1643 if (!res && size != 0)
1644 _gfortran_os_error ("Allocation would exceed memory limit");
1649 gfc_call_realloc (stmtblock_t
* block
, tree mem
, tree size
)
1651 tree msg
, res
, nonzero
, null_result
, tmp
;
1652 tree type
= TREE_TYPE (mem
);
1654 /* Only evaluate the size once. */
1655 size
= save_expr (fold_convert (size_type_node
, size
));
1657 /* Create a variable to hold the result. */
1658 res
= gfc_create_var (type
, NULL
);
1660 /* Call realloc and check the result. */
1661 tmp
= build_call_expr_loc (input_location
,
1662 builtin_decl_explicit (BUILT_IN_REALLOC
), 2,
1663 fold_convert (pvoid_type_node
, mem
), size
);
1664 gfc_add_modify (block
, res
, fold_convert (type
, tmp
));
1665 null_result
= fold_build2_loc (input_location
, EQ_EXPR
, logical_type_node
,
1666 res
, build_int_cst (pvoid_type_node
, 0));
1667 nonzero
= fold_build2_loc (input_location
, NE_EXPR
, logical_type_node
, size
,
1668 build_int_cst (size_type_node
, 0));
1669 null_result
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, logical_type_node
,
1670 null_result
, nonzero
);
1671 msg
= gfc_build_addr_expr (pchar_type_node
, gfc_build_localized_cstring_const
1672 ("Allocation would exceed memory limit"));
1673 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1675 build_call_expr_loc (input_location
,
1676 gfor_fndecl_os_error
, 1, msg
),
1677 build_empty_stmt (input_location
));
1678 gfc_add_expr_to_block (block
, tmp
);
1684 /* Add an expression to another one, either at the front or the back. */
1687 add_expr_to_chain (tree
* chain
, tree expr
, bool front
)
1689 if (expr
== NULL_TREE
|| IS_EMPTY_STMT (expr
))
1694 if (TREE_CODE (*chain
) != STATEMENT_LIST
)
1700 append_to_statement_list (tmp
, chain
);
1705 tree_stmt_iterator i
;
1707 i
= tsi_start (*chain
);
1708 tsi_link_before (&i
, expr
, TSI_CONTINUE_LINKING
);
1711 append_to_statement_list (expr
, chain
);
1718 /* Add a statement at the end of a block. */
1721 gfc_add_expr_to_block (stmtblock_t
* block
, tree expr
)
1724 add_expr_to_chain (&block
->head
, expr
, false);
1728 /* Add a statement at the beginning of a block. */
1731 gfc_prepend_expr_to_block (stmtblock_t
* block
, tree expr
)
1734 add_expr_to_chain (&block
->head
, expr
, true);
1738 /* Add a block the end of a block. */
1741 gfc_add_block_to_block (stmtblock_t
* block
, stmtblock_t
* append
)
1743 gcc_assert (append
);
1744 gcc_assert (!append
->has_scope
);
1746 gfc_add_expr_to_block (block
, append
->head
);
1747 append
->head
= NULL_TREE
;
1751 /* Save the current locus. The structure may not be complete, and should
1752 only be used with gfc_restore_backend_locus. */
1755 gfc_save_backend_locus (locus
* loc
)
1757 loc
->lb
= XCNEW (gfc_linebuf
);
1758 loc
->lb
->location
= input_location
;
1759 loc
->lb
->file
= gfc_current_backend_file
;
1763 /* Set the current locus. */
1766 gfc_set_backend_locus (locus
* loc
)
1768 gfc_current_backend_file
= loc
->lb
->file
;
1769 input_location
= loc
->lb
->location
;
1773 /* Restore the saved locus. Only used in conjunction with
1774 gfc_save_backend_locus, to free the memory when we are done. */
1777 gfc_restore_backend_locus (locus
* loc
)
1779 gfc_set_backend_locus (loc
);
1784 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
1785 This static function is wrapped by gfc_trans_code_cond and
1789 trans_code (gfc_code
* code
, tree cond
)
1795 return build_empty_stmt (input_location
);
1797 gfc_start_block (&block
);
1799 /* Translate statements one by one into GENERIC trees until we reach
1800 the end of this gfc_code branch. */
1801 for (; code
; code
= code
->next
)
1803 if (code
->here
!= 0)
1805 res
= gfc_trans_label_here (code
);
1806 gfc_add_expr_to_block (&block
, res
);
1809 gfc_current_locus
= code
->loc
;
1810 gfc_set_backend_locus (&code
->loc
);
1815 case EXEC_END_BLOCK
:
1816 case EXEC_END_NESTED_BLOCK
:
1817 case EXEC_END_PROCEDURE
:
1822 res
= gfc_trans_assign (code
);
1825 case EXEC_LABEL_ASSIGN
:
1826 res
= gfc_trans_label_assign (code
);
1829 case EXEC_POINTER_ASSIGN
:
1830 res
= gfc_trans_pointer_assign (code
);
1833 case EXEC_INIT_ASSIGN
:
1834 if (code
->expr1
->ts
.type
== BT_CLASS
)
1835 res
= gfc_trans_class_init_assign (code
);
1837 res
= gfc_trans_init_assign (code
);
1845 res
= gfc_trans_critical (code
);
1849 res
= gfc_trans_cycle (code
);
1853 res
= gfc_trans_exit (code
);
1857 res
= gfc_trans_goto (code
);
1861 res
= gfc_trans_entry (code
);
1865 res
= gfc_trans_pause (code
);
1869 case EXEC_ERROR_STOP
:
1870 res
= gfc_trans_stop (code
, code
->op
== EXEC_ERROR_STOP
);
1874 /* For MVBITS we've got the special exception that we need a
1875 dependency check, too. */
1877 bool is_mvbits
= false;
1879 if (code
->resolved_isym
)
1881 res
= gfc_conv_intrinsic_subroutine (code
);
1882 if (res
!= NULL_TREE
)
1886 if (code
->resolved_isym
1887 && code
->resolved_isym
->id
== GFC_ISYM_MVBITS
)
1890 res
= gfc_trans_call (code
, is_mvbits
, NULL_TREE
,
1896 res
= gfc_trans_call (code
, false, NULL_TREE
,
1900 case EXEC_ASSIGN_CALL
:
1901 res
= gfc_trans_call (code
, true, NULL_TREE
,
1906 res
= gfc_trans_return (code
);
1910 res
= gfc_trans_if (code
);
1913 case EXEC_ARITHMETIC_IF
:
1914 res
= gfc_trans_arithmetic_if (code
);
1918 res
= gfc_trans_block_construct (code
);
1922 res
= gfc_trans_do (code
, cond
);
1925 case EXEC_DO_CONCURRENT
:
1926 res
= gfc_trans_do_concurrent (code
);
1930 res
= gfc_trans_do_while (code
);
1934 res
= gfc_trans_select (code
);
1937 case EXEC_SELECT_TYPE
:
1938 res
= gfc_trans_select_type (code
);
1942 res
= gfc_trans_flush (code
);
1946 case EXEC_SYNC_IMAGES
:
1947 case EXEC_SYNC_MEMORY
:
1948 res
= gfc_trans_sync (code
, code
->op
);
1953 res
= gfc_trans_lock_unlock (code
, code
->op
);
1956 case EXEC_EVENT_POST
:
1957 case EXEC_EVENT_WAIT
:
1958 res
= gfc_trans_event_post_wait (code
, code
->op
);
1961 case EXEC_FAIL_IMAGE
:
1962 res
= gfc_trans_fail_image (code
);
1966 res
= gfc_trans_forall (code
);
1969 case EXEC_FORM_TEAM
:
1970 res
= gfc_trans_form_team (code
);
1973 case EXEC_CHANGE_TEAM
:
1974 res
= gfc_trans_change_team (code
);
1978 res
= gfc_trans_end_team (code
);
1981 case EXEC_SYNC_TEAM
:
1982 res
= gfc_trans_sync_team (code
);
1986 res
= gfc_trans_where (code
);
1990 res
= gfc_trans_allocate (code
);
1993 case EXEC_DEALLOCATE
:
1994 res
= gfc_trans_deallocate (code
);
1998 res
= gfc_trans_open (code
);
2002 res
= gfc_trans_close (code
);
2006 res
= gfc_trans_read (code
);
2010 res
= gfc_trans_write (code
);
2014 res
= gfc_trans_iolength (code
);
2017 case EXEC_BACKSPACE
:
2018 res
= gfc_trans_backspace (code
);
2022 res
= gfc_trans_endfile (code
);
2026 res
= gfc_trans_inquire (code
);
2030 res
= gfc_trans_wait (code
);
2034 res
= gfc_trans_rewind (code
);
2038 res
= gfc_trans_transfer (code
);
2042 res
= gfc_trans_dt_end (code
);
2045 case EXEC_OMP_ATOMIC
:
2046 case EXEC_OMP_BARRIER
:
2047 case EXEC_OMP_CANCEL
:
2048 case EXEC_OMP_CANCELLATION_POINT
:
2049 case EXEC_OMP_CRITICAL
:
2050 case EXEC_OMP_DISTRIBUTE
:
2051 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
2052 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
2053 case EXEC_OMP_DISTRIBUTE_SIMD
:
2055 case EXEC_OMP_DO_SIMD
:
2056 case EXEC_OMP_FLUSH
:
2057 case EXEC_OMP_MASTER
:
2058 case EXEC_OMP_ORDERED
:
2059 case EXEC_OMP_PARALLEL
:
2060 case EXEC_OMP_PARALLEL_DO
:
2061 case EXEC_OMP_PARALLEL_DO_SIMD
:
2062 case EXEC_OMP_PARALLEL_SECTIONS
:
2063 case EXEC_OMP_PARALLEL_WORKSHARE
:
2064 case EXEC_OMP_SECTIONS
:
2066 case EXEC_OMP_SINGLE
:
2067 case EXEC_OMP_TARGET
:
2068 case EXEC_OMP_TARGET_DATA
:
2069 case EXEC_OMP_TARGET_ENTER_DATA
:
2070 case EXEC_OMP_TARGET_EXIT_DATA
:
2071 case EXEC_OMP_TARGET_PARALLEL
:
2072 case EXEC_OMP_TARGET_PARALLEL_DO
:
2073 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
2074 case EXEC_OMP_TARGET_SIMD
:
2075 case EXEC_OMP_TARGET_TEAMS
:
2076 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
2077 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
2078 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
2079 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
2080 case EXEC_OMP_TARGET_UPDATE
:
2082 case EXEC_OMP_TASKGROUP
:
2083 case EXEC_OMP_TASKLOOP
:
2084 case EXEC_OMP_TASKLOOP_SIMD
:
2085 case EXEC_OMP_TASKWAIT
:
2086 case EXEC_OMP_TASKYIELD
:
2087 case EXEC_OMP_TEAMS
:
2088 case EXEC_OMP_TEAMS_DISTRIBUTE
:
2089 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
2090 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
2091 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
2092 case EXEC_OMP_WORKSHARE
:
2093 res
= gfc_trans_omp_directive (code
);
2096 case EXEC_OACC_CACHE
:
2097 case EXEC_OACC_WAIT
:
2098 case EXEC_OACC_UPDATE
:
2099 case EXEC_OACC_LOOP
:
2100 case EXEC_OACC_HOST_DATA
:
2101 case EXEC_OACC_DATA
:
2102 case EXEC_OACC_KERNELS
:
2103 case EXEC_OACC_KERNELS_LOOP
:
2104 case EXEC_OACC_PARALLEL
:
2105 case EXEC_OACC_PARALLEL_LOOP
:
2106 case EXEC_OACC_ENTER_DATA
:
2107 case EXEC_OACC_EXIT_DATA
:
2108 case EXEC_OACC_ATOMIC
:
2109 case EXEC_OACC_DECLARE
:
2110 res
= gfc_trans_oacc_directive (code
);
2114 gfc_internal_error ("gfc_trans_code(): Bad statement code");
2117 gfc_set_backend_locus (&code
->loc
);
2119 if (res
!= NULL_TREE
&& ! IS_EMPTY_STMT (res
))
2121 if (TREE_CODE (res
) != STATEMENT_LIST
)
2122 SET_EXPR_LOCATION (res
, input_location
);
2124 /* Add the new statement to the block. */
2125 gfc_add_expr_to_block (&block
, res
);
2129 /* Return the finished block. */
2130 return gfc_finish_block (&block
);
2134 /* Translate an executable statement with condition, cond. The condition is
2135 used by gfc_trans_do to test for IO result conditions inside implied
2136 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
2139 gfc_trans_code_cond (gfc_code
* code
, tree cond
)
2141 return trans_code (code
, cond
);
2144 /* Translate an executable statement without condition. */
2147 gfc_trans_code (gfc_code
* code
)
2149 return trans_code (code
, NULL_TREE
);
2153 /* This function is called after a complete program unit has been parsed
2157 gfc_generate_code (gfc_namespace
* ns
)
2160 if (ns
->is_block_data
)
2162 gfc_generate_block_data (ns
);
2166 gfc_generate_function_code (ns
);
2170 /* This function is called after a complete module has been parsed
2174 gfc_generate_module_code (gfc_namespace
* ns
)
2177 struct module_htab_entry
*entry
;
2179 gcc_assert (ns
->proc_name
->backend_decl
== NULL
);
2180 ns
->proc_name
->backend_decl
2181 = build_decl (ns
->proc_name
->declared_at
.lb
->location
,
2182 NAMESPACE_DECL
, get_identifier (ns
->proc_name
->name
),
2184 entry
= gfc_find_module (ns
->proc_name
->name
);
2185 if (entry
->namespace_decl
)
2186 /* Buggy sourcecode, using a module before defining it? */
2187 entry
->decls
->empty ();
2188 entry
->namespace_decl
= ns
->proc_name
->backend_decl
;
2190 gfc_generate_module_vars (ns
);
2192 /* We need to generate all module function prototypes first, to allow
2194 for (n
= ns
->contained
; n
; n
= n
->sibling
)
2201 gfc_create_function_decl (n
, false);
2202 DECL_CONTEXT (n
->proc_name
->backend_decl
) = ns
->proc_name
->backend_decl
;
2203 gfc_module_add_decl (entry
, n
->proc_name
->backend_decl
);
2204 for (el
= ns
->entries
; el
; el
= el
->next
)
2206 DECL_CONTEXT (el
->sym
->backend_decl
) = ns
->proc_name
->backend_decl
;
2207 gfc_module_add_decl (entry
, el
->sym
->backend_decl
);
2211 for (n
= ns
->contained
; n
; n
= n
->sibling
)
2216 gfc_generate_function_code (n
);
2221 /* Initialize an init/cleanup block with existing code. */
2224 gfc_start_wrapped_block (gfc_wrapped_block
* block
, tree code
)
2228 block
->init
= NULL_TREE
;
2230 block
->cleanup
= NULL_TREE
;
2234 /* Add a new pair of initializers/clean-up code. */
2237 gfc_add_init_cleanup (gfc_wrapped_block
* block
, tree init
, tree cleanup
)
2241 /* The new pair of init/cleanup should be "wrapped around" the existing
2242 block of code, thus the initialization is added to the front and the
2243 cleanup to the back. */
2244 add_expr_to_chain (&block
->init
, init
, true);
2245 add_expr_to_chain (&block
->cleanup
, cleanup
, false);
2249 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2252 gfc_finish_wrapped_block (gfc_wrapped_block
* block
)
2258 /* Build the final expression. For this, just add init and body together,
2259 and put clean-up with that into a TRY_FINALLY_EXPR. */
2260 result
= block
->init
;
2261 add_expr_to_chain (&result
, block
->code
, false);
2263 result
= build2_loc (input_location
, TRY_FINALLY_EXPR
, void_type_node
,
2264 result
, block
->cleanup
);
2266 /* Clear the block. */
2267 block
->init
= NULL_TREE
;
2268 block
->code
= NULL_TREE
;
2269 block
->cleanup
= NULL_TREE
;
2275 /* Helper function for marking a boolean expression tree as unlikely. */
2278 gfc_unlikely (tree cond
, enum br_predictor predictor
)
2284 cond
= fold_convert (long_integer_type_node
, cond
);
2285 tmp
= build_zero_cst (long_integer_type_node
);
2286 cond
= build_call_expr_loc (input_location
,
2287 builtin_decl_explicit (BUILT_IN_EXPECT
),
2289 build_int_cst (integer_type_node
,
2296 /* Helper function for marking a boolean expression tree as likely. */
2299 gfc_likely (tree cond
, enum br_predictor predictor
)
2305 cond
= fold_convert (long_integer_type_node
, cond
);
2306 tmp
= build_one_cst (long_integer_type_node
);
2307 cond
= build_call_expr_loc (input_location
,
2308 builtin_decl_explicit (BUILT_IN_EXPECT
),
2310 build_int_cst (integer_type_node
,
2317 /* Get the string length for a deferred character length component. */
2320 gfc_deferred_strlen (gfc_component
*c
, tree
*decl
)
2322 char name
[GFC_MAX_SYMBOL_LEN
+9];
2323 gfc_component
*strlen
;
2324 if (!(c
->ts
.type
== BT_CHARACTER
2325 && (c
->ts
.deferred
|| c
->attr
.pdt_string
)))
2327 sprintf (name
, "_%s_length", c
->name
);
2328 for (strlen
= c
; strlen
; strlen
= strlen
->next
)
2329 if (strcmp (strlen
->name
, name
) == 0)
2331 *decl
= strlen
? strlen
->backend_decl
: NULL_TREE
;
2332 return strlen
!= NULL
;