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