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