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