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