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