1/* Backend function setup
2 Copyright (C) 2002-2024 Free Software Foundation, Inc.
3 Contributed by Paul Brook
4
5This file is part of GCC.
6
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
9Software Foundation; either version 3, or (at your option) any later
10version.
11
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.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21/* trans-decl.cc -- Handling of backend function and variable decls, etc */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "target.h"
27#include "function.h"
28#include "tree.h"
29#include "gfortran.h"
30#include "gimple-expr.h" /* For create_tmp_var_raw. */
31#include "trans.h"
32#include "stringpool.h"
33#include "cgraph.h"
34#include "fold-const.h"
35#include "stor-layout.h"
36#include "varasm.h"
37#include "attribs.h"
38#include "dumpfile.h"
39#include "toplev.h" /* For announce_function. */
40#include "debug.h"
41#include "constructor.h"
42#include "trans-types.h"
43#include "trans-array.h"
44#include "trans-const.h"
45/* Only for gfc_trans_code. Shouldn't need to include this. */
46#include "trans-stmt.h"
47#include "gomp-constants.h"
48#include "gimplify.h"
49#include "omp-general.h"
50#include "attr-fnspec.h"
51#include "tree-iterator.h"
52
53#define MAX_LABEL_VALUE 99999
54
55
56/* Holds the result of the function if no result variable specified. */
57
58static GTY(()) tree current_fake_result_decl;
59static GTY(()) tree parent_fake_result_decl;
60
61
62/* Holds the variable DECLs for the current function. */
63
64static GTY(()) tree saved_function_decls;
65static GTY(()) tree saved_parent_function_decls;
66
67/* Holds the variable DECLs that are locals. */
68
69static GTY(()) tree saved_local_decls;
70
71/* The namespace of the module we're currently generating. Only used while
72 outputting decls for module variables. Do not rely on this being set. */
73
74static gfc_namespace *module_namespace;
75
76/* The currently processed procedure symbol. */
77static gfc_symbol* current_procedure_symbol = NULL;
78
79/* The currently processed module. */
80static struct module_htab_entry *cur_module;
81
82/* With -fcoarray=lib: For generating the registering call
83 of static coarrays. */
84static bool has_coarray_vars;
85static stmtblock_t caf_init_block;
86
87
88/* List of static constructor functions. */
89
90tree gfc_static_ctors;
91
92
93/* Whether we've seen a symbol from an IEEE module in the namespace. */
94static int seen_ieee_symbol;
95
96/* Function declarations for builtin library functions. */
97
98tree gfor_fndecl_pause_numeric;
99tree gfor_fndecl_pause_string;
100tree gfor_fndecl_stop_numeric;
101tree gfor_fndecl_stop_string;
102tree gfor_fndecl_error_stop_numeric;
103tree gfor_fndecl_error_stop_string;
104tree gfor_fndecl_runtime_error;
105tree gfor_fndecl_runtime_error_at;
106tree gfor_fndecl_runtime_warning_at;
107tree gfor_fndecl_os_error_at;
108tree gfor_fndecl_generate_error;
109tree gfor_fndecl_set_args;
110tree gfor_fndecl_set_fpe;
111tree gfor_fndecl_set_options;
112tree gfor_fndecl_set_convert;
113tree gfor_fndecl_set_record_marker;
114tree gfor_fndecl_set_max_subrecord_length;
115tree gfor_fndecl_ctime;
116tree gfor_fndecl_fdate;
117tree gfor_fndecl_ttynam;
118tree gfor_fndecl_in_pack;
119tree gfor_fndecl_in_unpack;
120tree gfor_fndecl_associated;
121tree gfor_fndecl_system_clock4;
122tree gfor_fndecl_system_clock8;
123tree gfor_fndecl_ieee_procedure_entry;
124tree gfor_fndecl_ieee_procedure_exit;
125
126/* Coarray run-time library function decls. */
127tree gfor_fndecl_caf_init;
128tree gfor_fndecl_caf_finalize;
129tree gfor_fndecl_caf_this_image;
130tree gfor_fndecl_caf_num_images;
131tree gfor_fndecl_caf_register;
132tree gfor_fndecl_caf_deregister;
133tree gfor_fndecl_caf_get;
134tree gfor_fndecl_caf_send;
135tree gfor_fndecl_caf_sendget;
136tree gfor_fndecl_caf_get_by_ref;
137tree gfor_fndecl_caf_send_by_ref;
138tree gfor_fndecl_caf_sendget_by_ref;
139tree gfor_fndecl_caf_sync_all;
140tree gfor_fndecl_caf_sync_memory;
141tree gfor_fndecl_caf_sync_images;
142tree gfor_fndecl_caf_stop_str;
143tree gfor_fndecl_caf_stop_numeric;
144tree gfor_fndecl_caf_error_stop;
145tree gfor_fndecl_caf_error_stop_str;
146tree gfor_fndecl_caf_atomic_def;
147tree gfor_fndecl_caf_atomic_ref;
148tree gfor_fndecl_caf_atomic_cas;
149tree gfor_fndecl_caf_atomic_op;
150tree gfor_fndecl_caf_lock;
151tree gfor_fndecl_caf_unlock;
152tree gfor_fndecl_caf_event_post;
153tree gfor_fndecl_caf_event_wait;
154tree gfor_fndecl_caf_event_query;
155tree gfor_fndecl_caf_fail_image;
156tree gfor_fndecl_caf_failed_images;
157tree gfor_fndecl_caf_image_status;
158tree gfor_fndecl_caf_stopped_images;
159tree gfor_fndecl_caf_form_team;
160tree gfor_fndecl_caf_change_team;
161tree gfor_fndecl_caf_end_team;
162tree gfor_fndecl_caf_sync_team;
163tree gfor_fndecl_caf_get_team;
164tree gfor_fndecl_caf_team_number;
165tree gfor_fndecl_co_broadcast;
166tree gfor_fndecl_co_max;
167tree gfor_fndecl_co_min;
168tree gfor_fndecl_co_reduce;
169tree gfor_fndecl_co_sum;
170tree gfor_fndecl_caf_is_present;
171tree gfor_fndecl_caf_random_init;
172
173
174/* Math functions. Many other math functions are handled in
175 trans-intrinsic.cc. */
176
177gfc_powdecl_list gfor_fndecl_math_powi[4][3];
178tree gfor_fndecl_math_ishftc4;
179tree gfor_fndecl_math_ishftc8;
180tree gfor_fndecl_math_ishftc16;
181
182
183/* String functions. */
184
185tree gfor_fndecl_compare_string;
186tree gfor_fndecl_concat_string;
187tree gfor_fndecl_string_len_trim;
188tree gfor_fndecl_string_index;
189tree gfor_fndecl_string_scan;
190tree gfor_fndecl_string_verify;
191tree gfor_fndecl_string_trim;
192tree gfor_fndecl_string_minmax;
193tree gfor_fndecl_adjustl;
194tree gfor_fndecl_adjustr;
195tree gfor_fndecl_select_string;
196tree gfor_fndecl_compare_string_char4;
197tree gfor_fndecl_concat_string_char4;
198tree gfor_fndecl_string_len_trim_char4;
199tree gfor_fndecl_string_index_char4;
200tree gfor_fndecl_string_scan_char4;
201tree gfor_fndecl_string_verify_char4;
202tree gfor_fndecl_string_trim_char4;
203tree gfor_fndecl_string_minmax_char4;
204tree gfor_fndecl_adjustl_char4;
205tree gfor_fndecl_adjustr_char4;
206tree gfor_fndecl_select_string_char4;
207
208
209/* Conversion between character kinds. */
210tree gfor_fndecl_convert_char1_to_char4;
211tree gfor_fndecl_convert_char4_to_char1;
212
213
214/* Other misc. runtime library functions. */
215tree gfor_fndecl_iargc;
216tree gfor_fndecl_kill;
217tree gfor_fndecl_kill_sub;
218tree gfor_fndecl_is_contiguous0;
219
220
221/* Intrinsic functions implemented in Fortran. */
222tree gfor_fndecl_sc_kind;
223tree gfor_fndecl_si_kind;
224tree gfor_fndecl_sr_kind;
225
226/* BLAS gemm functions. */
227tree gfor_fndecl_sgemm;
228tree gfor_fndecl_dgemm;
229tree gfor_fndecl_cgemm;
230tree gfor_fndecl_zgemm;
231
232/* RANDOM_INIT function. */
233tree gfor_fndecl_random_init; /* libgfortran, 1 image only. */
234
235static void
236gfc_add_decl_to_parent_function (tree decl)
237{
238 gcc_assert (decl);
239 DECL_CONTEXT (decl) = DECL_CONTEXT (current_function_decl);
240 DECL_NONLOCAL (decl) = 1;
241 DECL_CHAIN (decl) = saved_parent_function_decls;
242 saved_parent_function_decls = decl;
243}
244
245void
246gfc_add_decl_to_function (tree decl)
247{
248 gcc_assert (decl);
249 TREE_USED (decl) = 1;
250 DECL_CONTEXT (decl) = current_function_decl;
251 DECL_CHAIN (decl) = saved_function_decls;
252 saved_function_decls = decl;
253}
254
255static void
256add_decl_as_local (tree decl)
257{
258 gcc_assert (decl);
259 TREE_USED (decl) = 1;
260 DECL_CONTEXT (decl) = current_function_decl;
261 DECL_CHAIN (decl) = saved_local_decls;
262 saved_local_decls = decl;
263}
264
265
266/* Build a backend label declaration. Set TREE_USED for named labels.
267 The context of the label is always the current_function_decl. All
268 labels are marked artificial. */
269
270tree
271gfc_build_label_decl (tree label_id)
272{
273 /* 2^32 temporaries should be enough. */
274 static unsigned int tmp_num = 1;
275 tree label_decl;
276 char *label_name;
277
278 if (label_id == NULL_TREE)
279 {
280 /* Build an internal label name. */
281 ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++);
282 label_id = get_identifier (label_name);
283 }
284 else
285 label_name = NULL;
286
287 /* Build the LABEL_DECL node. Labels have no type. */
288 label_decl = build_decl (input_location,
289 LABEL_DECL, label_id, void_type_node);
290 DECL_CONTEXT (label_decl) = current_function_decl;
291 SET_DECL_MODE (label_decl, VOIDmode);
292
293 /* We always define the label as used, even if the original source
294 file never references the label. We don't want all kinds of
295 spurious warnings for old-style Fortran code with too many
296 labels. */
297 TREE_USED (label_decl) = 1;
298
299 DECL_ARTIFICIAL (label_decl) = 1;
300 return label_decl;
301}
302
303
304/* Set the backend source location of a decl. */
305
306void
307gfc_set_decl_location (tree decl, locus * loc)
308{
309 DECL_SOURCE_LOCATION (decl) = gfc_get_location (loc);
310}
311
312
313/* Return the backend label declaration for a given label structure,
314 or create it if it doesn't exist yet. */
315
316tree
317gfc_get_label_decl (gfc_st_label * lp)
318{
319 if (lp->backend_decl)
320 return lp->backend_decl;
321 else
322 {
323 char label_name[GFC_MAX_SYMBOL_LEN + 1];
324 tree label_decl;
325
326 /* Validate the label declaration from the front end. */
327 gcc_assert (lp != NULL && lp->value <= MAX_LABEL_VALUE);
328
329 /* Build a mangled name for the label. */
330 sprintf (s: label_name, format: "__label_%.6d", lp->value);
331
332 /* Build the LABEL_DECL node. */
333 label_decl = gfc_build_label_decl (get_identifier (label_name));
334
335 /* Tell the debugger where the label came from. */
336 if (lp->value <= MAX_LABEL_VALUE) /* An internal label. */
337 gfc_set_decl_location (decl: label_decl, loc: &lp->where);
338 else
339 DECL_ARTIFICIAL (label_decl) = 1;
340
341 /* Store the label in the label list and return the LABEL_DECL. */
342 lp->backend_decl = label_decl;
343 return label_decl;
344 }
345}
346
347/* Return the name of an identifier. */
348
349static const char *
350sym_identifier (gfc_symbol *sym)
351{
352 if (sym->attr.is_main_program && strcmp (s1: sym->name, s2: "main") == 0)
353 return "MAIN__";
354 else
355 return sym->name;
356}
357
358/* Convert a gfc_symbol to an identifier of the same name. */
359
360static tree
361gfc_sym_identifier (gfc_symbol * sym)
362{
363 return get_identifier (sym_identifier (sym));
364}
365
366/* Construct mangled name from symbol name. */
367
368static const char *
369mangled_identifier (gfc_symbol *sym)
370{
371 gfc_symbol *proc = sym->ns->proc_name;
372 static char name[3*GFC_MAX_MANGLED_SYMBOL_LEN + 14];
373 /* Prevent the mangling of identifiers that have an assigned
374 binding label (mainly those that are bind(c)). */
375
376 if (sym->attr.is_bind_c == 1 && sym->binding_label)
377 return sym->binding_label;
378
379 if (!sym->fn_result_spec
380 || (sym->module && !(proc && proc->attr.flavor == FL_PROCEDURE)))
381 {
382 if (sym->module == NULL)
383 return sym_identifier (sym);
384 else
385 snprintf (s: name, maxlen: sizeof name, format: "__%s_MOD_%s", sym->module, sym->name);
386 }
387 else
388 {
389 /* This is an entity that is actually local to a module procedure
390 that appears in the result specification expression. Since
391 sym->module will be a zero length string, we use ns->proc_name
392 to provide the module name instead. */
393 if (proc && proc->module)
394 snprintf (s: name, maxlen: sizeof name, format: "__%s_MOD__%s_PROC_%s",
395 proc->module, proc->name, sym->name);
396 else
397 snprintf (s: name, maxlen: sizeof name, format: "__%s_PROC_%s",
398 proc->name, sym->name);
399 }
400
401 return name;
402}
403
404/* Get mangled identifier, adding the symbol to the global table if
405 it is not yet already there. */
406
407static tree
408gfc_sym_mangled_identifier (gfc_symbol * sym)
409{
410 tree result;
411 gfc_gsymbol *gsym;
412 const char *name;
413
414 name = mangled_identifier (sym);
415 result = get_identifier (name);
416
417 gsym = gfc_find_gsymbol (gfc_gsym_root, name);
418 if (gsym == NULL)
419 {
420 gsym = gfc_get_gsymbol (name, bind_c: false);
421 gsym->ns = sym->ns;
422 gsym->sym_name = sym->name;
423 }
424
425 return result;
426}
427
428/* Construct mangled function name from symbol name. */
429
430static tree
431gfc_sym_mangled_function_id (gfc_symbol * sym)
432{
433 int has_underscore;
434 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
435
436 /* It may be possible to simply use the binding label if it's
437 provided, and remove the other checks. Then we could use it
438 for other things if we wished. */
439 if ((sym->attr.is_bind_c == 1 || sym->attr.is_iso_c == 1) &&
440 sym->binding_label)
441 /* use the binding label rather than the mangled name */
442 return get_identifier (sym->binding_label);
443
444 if ((sym->module == NULL || sym->attr.proc == PROC_EXTERNAL
445 || (sym->module != NULL && (sym->attr.external
446 || sym->attr.if_source == IFSRC_IFBODY)))
447 && !sym->attr.module_procedure)
448 {
449 /* Main program is mangled into MAIN__. */
450 if (sym->attr.is_main_program)
451 return get_identifier ("MAIN__");
452
453 /* Intrinsic procedures are never mangled. */
454 if (sym->attr.proc == PROC_INTRINSIC)
455 return get_identifier (sym->name);
456
457 if (flag_underscoring)
458 {
459 has_underscore = strchr (s: sym->name, c: '_') != 0;
460 if (flag_second_underscore && has_underscore)
461 snprintf (s: name, maxlen: sizeof name, format: "%s__", sym->name);
462 else
463 snprintf (s: name, maxlen: sizeof name, format: "%s_", sym->name);
464 return get_identifier (name);
465 }
466 else
467 return get_identifier (sym->name);
468 }
469 else
470 {
471 snprintf (s: name, maxlen: sizeof name, format: "__%s_MOD_%s", sym->module, sym->name);
472 return get_identifier (name);
473 }
474}
475
476
477void
478gfc_set_decl_assembler_name (tree decl, tree name)
479{
480 tree target_mangled = targetm.mangle_decl_assembler_name (decl, name);
481 SET_DECL_ASSEMBLER_NAME (decl, target_mangled);
482}
483
484
485/* Returns true if a variable of specified size should go on the stack. */
486
487bool
488gfc_can_put_var_on_stack (tree size)
489{
490 unsigned HOST_WIDE_INT low;
491
492 if (!INTEGER_CST_P (size))
493 return 0;
494
495 if (flag_max_stack_var_size < 0)
496 return 1;
497
498 if (!tree_fits_uhwi_p (size))
499 return 0;
500
501 low = TREE_INT_CST_LOW (size);
502 if (low > (unsigned HOST_WIDE_INT) flag_max_stack_var_size)
503 return 0;
504
505/* TODO: Set a per-function stack size limit. */
506
507 return 1;
508}
509
510
511/* gfc_finish_cray_pointee sets DECL_VALUE_EXPR for a Cray pointee to
512 an expression involving its corresponding pointer. There are
513 2 cases; one for variable size arrays, and one for everything else,
514 because variable-sized arrays require one fewer level of
515 indirection. */
516
517static void
518gfc_finish_cray_pointee (tree decl, gfc_symbol *sym)
519{
520 tree ptr_decl = gfc_get_symbol_decl (sym->cp_pointer);
521 tree value;
522
523 /* Parameters need to be dereferenced. */
524 if (sym->cp_pointer->attr.dummy)
525 ptr_decl = build_fold_indirect_ref_loc (input_location,
526 ptr_decl);
527
528 /* Check to see if we're dealing with a variable-sized array. */
529 if (sym->attr.dimension
530 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
531 {
532 /* These decls will be dereferenced later, so we don't dereference
533 them here. */
534 value = convert (TREE_TYPE (decl), ptr_decl);
535 }
536 else
537 {
538 ptr_decl = convert (build_pointer_type (TREE_TYPE (decl)),
539 ptr_decl);
540 value = build_fold_indirect_ref_loc (input_location,
541 ptr_decl);
542 }
543
544 SET_DECL_VALUE_EXPR (decl, value);
545 DECL_HAS_VALUE_EXPR_P (decl) = 1;
546 GFC_DECL_CRAY_POINTEE (decl) = 1;
547}
548
549
550/* Finish processing of a declaration without an initial value. */
551
552static void
553gfc_finish_decl (tree decl)
554{
555 gcc_assert (TREE_CODE (decl) == PARM_DECL
556 || DECL_INITIAL (decl) == NULL_TREE);
557
558 if (!VAR_P (decl))
559 return;
560
561 if (DECL_SIZE (decl) == NULL_TREE
562 && COMPLETE_TYPE_P (TREE_TYPE (decl)))
563 layout_decl (decl, 0);
564
565 /* A few consistency checks. */
566 /* A static variable with an incomplete type is an error if it is
567 initialized. Also if it is not file scope. Otherwise, let it
568 through, but if it is not `extern' then it may cause an error
569 message later. */
570 /* An automatic variable with an incomplete type is an error. */
571
572 /* We should know the storage size. */
573 gcc_assert (DECL_SIZE (decl) != NULL_TREE
574 || (TREE_STATIC (decl)
575 ? (!DECL_INITIAL (decl) || !DECL_CONTEXT (decl))
576 : DECL_EXTERNAL (decl)));
577
578 /* The storage size should be constant. */
579 gcc_assert ((!DECL_EXTERNAL (decl) && !TREE_STATIC (decl))
580 || !DECL_SIZE (decl)
581 || TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST);
582}
583
584
585/* Handle setting of GFC_DECL_SCALAR* on DECL. */
586
587void
588gfc_finish_decl_attrs (tree decl, symbol_attribute *attr)
589{
590 if (!attr->dimension && !attr->codimension)
591 {
592 /* Handle scalar allocatable variables. */
593 if (attr->allocatable)
594 {
595 gfc_allocate_lang_decl (decl);
596 GFC_DECL_SCALAR_ALLOCATABLE (decl) = 1;
597 }
598 /* Handle scalar pointer variables. */
599 if (attr->pointer)
600 {
601 gfc_allocate_lang_decl (decl);
602 GFC_DECL_SCALAR_POINTER (decl) = 1;
603 }
604 if (attr->target)
605 {
606 gfc_allocate_lang_decl (decl);
607 GFC_DECL_SCALAR_TARGET (decl) = 1;
608 }
609 }
610}
611
612
613/* Apply symbol attributes to a variable, and add it to the function scope. */
614
615static void
616gfc_finish_var_decl (tree decl, gfc_symbol * sym)
617{
618 tree new_type;
619
620 /* Set DECL_VALUE_EXPR for Cray Pointees. */
621 if (sym->attr.cray_pointee)
622 gfc_finish_cray_pointee (decl, sym);
623
624 /* TREE_ADDRESSABLE means the address of this variable is actually needed.
625 This is the equivalent of the TARGET variables.
626 We also need to set this if the variable is passed by reference in a
627 CALL statement. */
628 if (sym->attr.target)
629 TREE_ADDRESSABLE (decl) = 1;
630
631 /* If it wasn't used we wouldn't be getting it. */
632 TREE_USED (decl) = 1;
633
634 if (sym->attr.flavor == FL_PARAMETER
635 && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
636 TREE_READONLY (decl) = 1;
637
638 /* Chain this decl to the pending declarations. Don't do pushdecl()
639 because this would add them to the current scope rather than the
640 function scope. */
641 if (current_function_decl != NULL_TREE)
642 {
643 if (sym->ns->proc_name
644 && (sym->ns->proc_name->backend_decl == current_function_decl
645 || sym->result == sym))
646 gfc_add_decl_to_function (decl);
647 else if (sym->ns->proc_name
648 && sym->ns->proc_name->attr.flavor == FL_LABEL)
649 /* This is a BLOCK construct. */
650 add_decl_as_local (decl);
651 else if (sym->ns->omp_affinity_iterators)
652 /* This is a block-local iterator. */
653 add_decl_as_local (decl);
654 else
655 gfc_add_decl_to_parent_function (decl);
656 }
657
658 if (sym->attr.cray_pointee)
659 return;
660
661 if(sym->attr.is_bind_c == 1 && sym->binding_label)
662 {
663 /* We need to put variables that are bind(c) into the common
664 segment of the object file, because this is what C would do.
665 gfortran would typically put them in either the BSS or
666 initialized data segments, and only mark them as common if
667 they were part of common blocks. However, if they are not put
668 into common space, then C cannot initialize global Fortran
669 variables that it interoperates with and the draft says that
670 either Fortran or C should be able to initialize it (but not
671 both, of course.) (J3/04-007, section 15.3). */
672 TREE_PUBLIC(decl) = 1;
673 DECL_COMMON(decl) = 1;
674 if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
675 {
676 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
677 DECL_VISIBILITY_SPECIFIED (decl) = true;
678 }
679 }
680
681 /* If a variable is USE associated, it's always external. */
682 if (sym->attr.use_assoc || sym->attr.used_in_submodule)
683 {
684 DECL_EXTERNAL (decl) = 1;
685 TREE_PUBLIC (decl) = 1;
686 }
687 else if (sym->fn_result_spec && !sym->ns->proc_name->module)
688 {
689
690 if (sym->ns->proc_name->attr.if_source != IFSRC_DECL)
691 DECL_EXTERNAL (decl) = 1;
692 else
693 TREE_STATIC (decl) = 1;
694
695 TREE_PUBLIC (decl) = 1;
696 }
697 else if (sym->module && !sym->attr.result && !sym->attr.dummy)
698 {
699 /* TODO: Don't set sym->module for result or dummy variables. */
700 gcc_assert (current_function_decl == NULL_TREE || sym->result == sym);
701
702 TREE_PUBLIC (decl) = 1;
703 TREE_STATIC (decl) = 1;
704 if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
705 {
706 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
707 DECL_VISIBILITY_SPECIFIED (decl) = true;
708 }
709 }
710
711 /* Derived types are a bit peculiar because of the possibility of
712 a default initializer; this must be applied each time the variable
713 comes into scope it therefore need not be static. These variables
714 are SAVE_NONE but have an initializer. Otherwise explicitly
715 initialized variables are SAVE_IMPLICIT and explicitly saved are
716 SAVE_EXPLICIT. */
717 if (!sym->attr.use_assoc
718 && (sym->attr.save != SAVE_NONE || sym->attr.data
719 || (sym->value && sym->ns->proc_name->attr.is_main_program)
720 || (flag_coarray == GFC_FCOARRAY_LIB
721 && sym->attr.codimension && !sym->attr.allocatable)))
722 TREE_STATIC (decl) = 1;
723
724 /* If derived-type variables with DTIO procedures are not made static
725 some bits of code referencing them get optimized away.
726 TODO Understand why this is so and fix it. */
727 if (!sym->attr.use_assoc
728 && ((sym->ts.type == BT_DERIVED
729 && sym->ts.u.derived->attr.has_dtio_procs)
730 || (sym->ts.type == BT_CLASS
731 && CLASS_DATA (sym)->ts.u.derived->attr.has_dtio_procs)))
732 TREE_STATIC (decl) = 1;
733
734 /* Treat asynchronous variables the same as volatile, for now. */
735 if (sym->attr.volatile_ || sym->attr.asynchronous)
736 {
737 TREE_THIS_VOLATILE (decl) = 1;
738 TREE_SIDE_EFFECTS (decl) = 1;
739 new_type = build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_VOLATILE);
740 TREE_TYPE (decl) = new_type;
741 }
742
743 /* Keep variables larger than max-stack-var-size off stack. */
744 if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive)
745 && !sym->attr.automatic
746 && !sym->attr.associate_var
747 && sym->attr.save != SAVE_EXPLICIT
748 && sym->attr.save != SAVE_IMPLICIT
749 && INTEGER_CST_P (DECL_SIZE_UNIT (decl))
750 && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
751 /* Put variable length auto array pointers always into stack. */
752 && (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
753 || sym->attr.dimension == 0
754 || sym->as->type != AS_EXPLICIT
755 || sym->attr.pointer
756 || sym->attr.allocatable)
757 && !DECL_ARTIFICIAL (decl))
758 {
759 if (flag_max_stack_var_size > 0
760 && !(sym->ns->proc_name
761 && sym->ns->proc_name->attr.is_main_program))
762 gfc_warning (opt: OPT_Wsurprising,
763 "Array %qs at %L is larger than limit set by "
764 "%<-fmax-stack-var-size=%>, moved from stack to static "
765 "storage. This makes the procedure unsafe when called "
766 "recursively, or concurrently from multiple threads. "
767 "Consider increasing the %<-fmax-stack-var-size=%> "
768 "limit (or use %<-frecursive%>, which implies "
769 "unlimited %<-fmax-stack-var-size%>) - or change the "
770 "code to use an ALLOCATABLE array. If the variable is "
771 "never accessed concurrently, this warning can be "
772 "ignored, and the variable could also be declared with "
773 "the SAVE attribute.",
774 sym->name, &sym->declared_at);
775
776 TREE_STATIC (decl) = 1;
777
778 /* Because the size of this variable isn't known until now, we may have
779 greedily added an initializer to this variable (in build_init_assign)
780 even though the max-stack-var-size indicates the variable should be
781 static. Therefore we rip out the automatic initializer here and
782 replace it with a static one. */
783 gfc_symtree *st = gfc_find_symtree (sym->ns->sym_root, sym->name);
784 gfc_code *prev = NULL;
785 gfc_code *code = sym->ns->code;
786 while (code && code->op == EXEC_INIT_ASSIGN)
787 {
788 /* Look for an initializer meant for this symbol. */
789 if (code->expr1->symtree == st)
790 {
791 if (prev)
792 prev->next = code->next;
793 else
794 sym->ns->code = code->next;
795
796 break;
797 }
798
799 prev = code;
800 code = code->next;
801 }
802 if (code && code->op == EXEC_INIT_ASSIGN)
803 {
804 /* Keep the init expression for a static initializer. */
805 sym->value = code->expr2;
806 /* Cleanup the defunct code object, without freeing the init expr. */
807 code->expr2 = NULL;
808 gfc_free_statement (code);
809 free (ptr: code);
810 }
811 }
812
813 /* Handle threadprivate variables. */
814 if (sym->attr.threadprivate
815 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
816 set_decl_tls_model (decl, decl_default_tls_model (decl));
817
818 /* Mark weak variables. */
819 if (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK))
820 declare_weak (decl);
821
822 gfc_finish_decl_attrs (decl, attr: &sym->attr);
823}
824
825
826/* Allocate the lang-specific part of a decl. */
827
828void
829gfc_allocate_lang_decl (tree decl)
830{
831 if (DECL_LANG_SPECIFIC (decl) == NULL)
832 DECL_LANG_SPECIFIC (decl) = ggc_cleared_alloc<struct lang_decl> ();
833}
834
835/* Remember a symbol to generate initialization/cleanup code at function
836 entry/exit. */
837
838static void
839gfc_defer_symbol_init (gfc_symbol * sym)
840{
841 gfc_symbol *p;
842 gfc_symbol *last;
843 gfc_symbol *head;
844
845 /* Don't add a symbol twice. */
846 if (sym->tlink)
847 return;
848
849 last = head = sym->ns->proc_name;
850 p = last->tlink;
851
852 /* Make sure that setup code for dummy variables which are used in the
853 setup of other variables is generated first. */
854 if (sym->attr.dummy)
855 {
856 /* Find the first dummy arg seen after us, or the first non-dummy arg.
857 This is a circular list, so don't go past the head. */
858 while (p != head
859 && (!p->attr.dummy || p->dummy_order > sym->dummy_order))
860 {
861 last = p;
862 p = p->tlink;
863 }
864 }
865 /* Insert in between last and p. */
866 last->tlink = sym;
867 sym->tlink = p;
868}
869
870
871/* Used in gfc_get_symbol_decl and gfc_get_derived_type to obtain the
872 backend_decl for a module symbol, if it all ready exists. If the
873 module gsymbol does not exist, it is created. If the symbol does
874 not exist, it is added to the gsymbol namespace. Returns true if
875 an existing backend_decl is found. */
876
877bool
878gfc_get_module_backend_decl (gfc_symbol *sym)
879{
880 gfc_gsymbol *gsym;
881 gfc_symbol *s;
882 gfc_symtree *st;
883
884 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module);
885
886 if (!gsym || (gsym->ns && gsym->type == GSYM_MODULE))
887 {
888 st = NULL;
889 s = NULL;
890
891 /* Check for a symbol with the same name. */
892 if (gsym)
893 gfc_find_symbol (sym->name, gsym->ns, 0, &s);
894
895 if (!s)
896 {
897 if (!gsym)
898 {
899 gsym = gfc_get_gsymbol (sym->module, bind_c: false);
900 gsym->type = GSYM_MODULE;
901 gsym->ns = gfc_get_namespace (NULL, 0);
902 }
903
904 st = gfc_new_symtree (&gsym->ns->sym_root, sym->name);
905 st->n.sym = sym;
906 sym->refs++;
907 }
908 else if (gfc_fl_struct (sym->attr.flavor))
909 {
910 if (s && s->attr.flavor == FL_PROCEDURE)
911 {
912 gfc_interface *intr;
913 gcc_assert (s->attr.generic);
914 for (intr = s->generic; intr; intr = intr->next)
915 if (gfc_fl_struct (intr->sym->attr.flavor))
916 {
917 s = intr->sym;
918 break;
919 }
920 }
921
922 /* Normally we can assume that s is a derived-type symbol since it
923 shares a name with the derived-type sym. However if sym is a
924 STRUCTURE, it may in fact share a name with any other basic type
925 variable. If s is in fact of derived type then we can continue
926 looking for a duplicate type declaration. */
927 if (sym->attr.flavor == FL_STRUCT && s->ts.type == BT_DERIVED)
928 {
929 s = s->ts.u.derived;
930 }
931
932 if (gfc_fl_struct (s->attr.flavor) && !s->backend_decl)
933 {
934 if (s->attr.flavor == FL_UNION)
935 s->backend_decl = gfc_get_union_type (s);
936 else
937 s->backend_decl = gfc_get_derived_type (derived: s);
938 }
939 gfc_copy_dt_decls_ifequal (s, sym, true);
940 return true;
941 }
942 else if (s->backend_decl)
943 {
944 if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
945 gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
946 true);
947 else if (sym->ts.type == BT_CHARACTER)
948 sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
949 sym->backend_decl = s->backend_decl;
950 return true;
951 }
952 }
953 return false;
954}
955
956
957/* Create an array index type variable with function scope. */
958
959static tree
960create_index_var (const char * pfx, int nest)
961{
962 tree decl;
963
964 decl = gfc_create_var_np (gfc_array_index_type, pfx);
965 if (nest)
966 gfc_add_decl_to_parent_function (decl);
967 else
968 gfc_add_decl_to_function (decl);
969 return decl;
970}
971
972
973/* Create variables to hold all the non-constant bits of info for a
974 descriptorless array. Remember these in the lang-specific part of the
975 type. */
976
977static void
978gfc_build_qualified_array (tree decl, gfc_symbol * sym)
979{
980 tree type;
981 int dim;
982 int nest;
983 gfc_namespace* procns;
984 symbol_attribute *array_attr;
985 gfc_array_spec *as;
986 bool is_classarray = IS_CLASS_ARRAY (sym);
987
988 type = TREE_TYPE (decl);
989 array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
990 as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
991
992 /* We just use the descriptor, if there is one. */
993 if (GFC_DESCRIPTOR_TYPE_P (type))
994 return;
995
996 gcc_assert (GFC_ARRAY_TYPE_P (type));
997 procns = gfc_find_proc_namespace (sym->ns);
998 nest = (procns->proc_name->backend_decl != current_function_decl)
999 && !sym->attr.contained;
1000
1001 if (array_attr->codimension && flag_coarray == GFC_FCOARRAY_LIB
1002 && as->type != AS_ASSUMED_SHAPE
1003 && GFC_TYPE_ARRAY_CAF_TOKEN (type) == NULL_TREE)
1004 {
1005 tree token;
1006 tree token_type = build_qualified_type (pvoid_type_node,
1007 TYPE_QUAL_RESTRICT);
1008
1009 if (sym->module && (sym->attr.use_assoc
1010 || sym->ns->proc_name->attr.flavor == FL_MODULE))
1011 {
1012 tree token_name
1013 = get_identifier (gfc_get_string (GFC_PREFIX ("caf_token%s"),
1014 IDENTIFIER_POINTER (gfc_sym_mangled_identifier (sym))));
1015 token = build_decl (DECL_SOURCE_LOCATION (decl), VAR_DECL, token_name,
1016 token_type);
1017 if (sym->attr.use_assoc)
1018 DECL_EXTERNAL (token) = 1;
1019 else
1020 TREE_STATIC (token) = 1;
1021
1022 TREE_PUBLIC (token) = 1;
1023
1024 if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
1025 {
1026 DECL_VISIBILITY (token) = VISIBILITY_HIDDEN;
1027 DECL_VISIBILITY_SPECIFIED (token) = true;
1028 }
1029 }
1030 else
1031 {
1032 token = gfc_create_var_np (token_type, "caf_token");
1033 TREE_STATIC (token) = 1;
1034 }
1035
1036 GFC_TYPE_ARRAY_CAF_TOKEN (type) = token;
1037 DECL_ARTIFICIAL (token) = 1;
1038 DECL_NONALIASED (token) = 1;
1039
1040 if (sym->module && !sym->attr.use_assoc)
1041 {
1042 pushdecl (token);
1043 DECL_CONTEXT (token) = sym->ns->proc_name->backend_decl;
1044 gfc_module_add_decl (cur_module, token);
1045 }
1046 else if (sym->attr.host_assoc
1047 && TREE_CODE (DECL_CONTEXT (current_function_decl))
1048 != TRANSLATION_UNIT_DECL)
1049 gfc_add_decl_to_parent_function (decl: token);
1050 else
1051 gfc_add_decl_to_function (decl: token);
1052 }
1053
1054 for (dim = 0; dim < GFC_TYPE_ARRAY_RANK (type); dim++)
1055 {
1056 if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
1057 {
1058 GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var (pfx: "lbound", nest);
1059 suppress_warning (GFC_TYPE_ARRAY_LBOUND (type, dim));
1060 }
1061 /* Don't try to use the unknown bound for assumed shape arrays. */
1062 if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
1063 && (as->type != AS_ASSUMED_SIZE
1064 || dim < GFC_TYPE_ARRAY_RANK (type) - 1))
1065 {
1066 GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var (pfx: "ubound", nest);
1067 suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim));
1068 }
1069
1070 if (GFC_TYPE_ARRAY_STRIDE (type, dim) == NULL_TREE)
1071 {
1072 GFC_TYPE_ARRAY_STRIDE (type, dim) = create_index_var (pfx: "stride", nest);
1073 suppress_warning (GFC_TYPE_ARRAY_STRIDE (type, dim));
1074 }
1075 }
1076 for (dim = GFC_TYPE_ARRAY_RANK (type);
1077 dim < GFC_TYPE_ARRAY_RANK (type) + GFC_TYPE_ARRAY_CORANK (type); dim++)
1078 {
1079 if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
1080 {
1081 GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var (pfx: "lbound", nest);
1082 suppress_warning (GFC_TYPE_ARRAY_LBOUND (type, dim));
1083 }
1084 /* Don't try to use the unknown ubound for the last coarray dimension. */
1085 if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
1086 && dim < GFC_TYPE_ARRAY_RANK (type) + GFC_TYPE_ARRAY_CORANK (type) - 1)
1087 {
1088 GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var (pfx: "ubound", nest);
1089 suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim));
1090 }
1091 }
1092 if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE)
1093 {
1094 GFC_TYPE_ARRAY_OFFSET (type) = gfc_create_var_np (gfc_array_index_type,
1095 "offset");
1096 suppress_warning (GFC_TYPE_ARRAY_OFFSET (type));
1097
1098 if (nest)
1099 gfc_add_decl_to_parent_function (GFC_TYPE_ARRAY_OFFSET (type));
1100 else
1101 gfc_add_decl_to_function (GFC_TYPE_ARRAY_OFFSET (type));
1102 }
1103
1104 if (GFC_TYPE_ARRAY_SIZE (type) == NULL_TREE
1105 && as->type != AS_ASSUMED_SIZE)
1106 {
1107 GFC_TYPE_ARRAY_SIZE (type) = create_index_var (pfx: "size", nest);
1108 suppress_warning (GFC_TYPE_ARRAY_SIZE (type));
1109 }
1110
1111 if (POINTER_TYPE_P (type))
1112 {
1113 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (type)));
1114 gcc_assert (TYPE_LANG_SPECIFIC (type)
1115 == TYPE_LANG_SPECIFIC (TREE_TYPE (type)));
1116 type = TREE_TYPE (type);
1117 }
1118
1119 if (! COMPLETE_TYPE_P (type) && GFC_TYPE_ARRAY_SIZE (type))
1120 {
1121 tree size, range;
1122
1123 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
1124 GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node);
1125 range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
1126 size);
1127 TYPE_DOMAIN (type) = range;
1128 layout_type (type);
1129 }
1130
1131 if (TYPE_NAME (type) != NULL_TREE && as->rank > 0
1132 && GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1) != NULL_TREE
1133 && VAR_P (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1)))
1134 {
1135 tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
1136
1137 for (dim = 0; dim < as->rank - 1; dim++)
1138 {
1139 gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
1140 gtype = TREE_TYPE (gtype);
1141 }
1142 gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
1143 if (TYPE_MAX_VALUE (TYPE_DOMAIN (gtype)) == NULL)
1144 TYPE_NAME (type) = NULL_TREE;
1145 }
1146
1147 if (TYPE_NAME (type) == NULL_TREE)
1148 {
1149 tree gtype = TREE_TYPE (type), rtype, type_decl;
1150
1151 for (dim = as->rank - 1; dim >= 0; dim--)
1152 {
1153 tree lbound, ubound;
1154 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
1155 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
1156 rtype = build_range_type (gfc_array_index_type, lbound, ubound);
1157 gtype = build_array_type (gtype, rtype);
1158 /* Ensure the bound variables aren't optimized out at -O0.
1159 For -O1 and above they often will be optimized out, but
1160 can be tracked by VTA. Also set DECL_NAMELESS, so that
1161 the artificial lbound.N or ubound.N DECL_NAME doesn't
1162 end up in debug info. */
1163 if (lbound
1164 && VAR_P (lbound)
1165 && DECL_ARTIFICIAL (lbound)
1166 && DECL_IGNORED_P (lbound))
1167 {
1168 if (DECL_NAME (lbound)
1169 && strstr (IDENTIFIER_POINTER (DECL_NAME (lbound)),
1170 needle: "lbound") != 0)
1171 DECL_NAMELESS (lbound) = 1;
1172 DECL_IGNORED_P (lbound) = 0;
1173 }
1174 if (ubound
1175 && VAR_P (ubound)
1176 && DECL_ARTIFICIAL (ubound)
1177 && DECL_IGNORED_P (ubound))
1178 {
1179 if (DECL_NAME (ubound)
1180 && strstr (IDENTIFIER_POINTER (DECL_NAME (ubound)),
1181 needle: "ubound") != 0)
1182 DECL_NAMELESS (ubound) = 1;
1183 DECL_IGNORED_P (ubound) = 0;
1184 }
1185 }
1186 TYPE_NAME (type) = type_decl = build_decl (input_location,
1187 TYPE_DECL, NULL, gtype);
1188 DECL_ORIGINAL_TYPE (type_decl) = gtype;
1189 }
1190}
1191
1192
1193/* For some dummy arguments we don't use the actual argument directly.
1194 Instead we create a local decl and use that. This allows us to perform
1195 initialization, and construct full type information. */
1196
1197static tree
1198gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
1199{
1200 tree decl;
1201 tree type;
1202 gfc_array_spec *as;
1203 symbol_attribute *array_attr;
1204 char *name;
1205 gfc_packed packed;
1206 int n;
1207 bool known_size;
1208 bool is_classarray = IS_CLASS_ARRAY (sym);
1209
1210 /* Use the array as and attr. */
1211 as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
1212 array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
1213
1214 /* The dummy is returned for pointer, allocatable or assumed rank arrays.
1215 For class arrays the information if sym is an allocatable or pointer
1216 object needs to be checked explicitly (IS_CLASS_ARRAY can be false for
1217 too many reasons to be of use here). */
1218 if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
1219 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
1220 || array_attr->allocatable
1221 || (as && as->type == AS_ASSUMED_RANK))
1222 return dummy;
1223
1224 /* Add to list of variables if not a fake result variable.
1225 These symbols are set on the symbol only, not on the class component. */
1226 if (sym->attr.result || sym->attr.dummy)
1227 gfc_defer_symbol_init (sym);
1228
1229 /* For a class array the array descriptor is in the _data component, while
1230 for a regular array the TREE_TYPE of the dummy is a pointer to the
1231 descriptor. */
1232 type = TREE_TYPE (is_classarray ? gfc_class_data_get (dummy)
1233 : TREE_TYPE (dummy));
1234 /* type now is the array descriptor w/o any indirection. */
1235 gcc_assert (TREE_CODE (dummy) == PARM_DECL
1236 && POINTER_TYPE_P (TREE_TYPE (dummy)));
1237
1238 /* Do we know the element size? */
1239 known_size = sym->ts.type != BT_CHARACTER
1240 || INTEGER_CST_P (sym->ts.u.cl->backend_decl);
1241
1242 if (known_size && !GFC_DESCRIPTOR_TYPE_P (type))
1243 {
1244 /* For descriptorless arrays with known element size the actual
1245 argument is sufficient. */
1246 gfc_build_qualified_array (decl: dummy, sym);
1247 return dummy;
1248 }
1249
1250 if (GFC_DESCRIPTOR_TYPE_P (type))
1251 {
1252 /* Create a descriptorless array pointer. */
1253 packed = PACKED_NO;
1254
1255 /* Even when -frepack-arrays is used, symbols with TARGET attribute
1256 are not repacked. */
1257 if (!flag_repack_arrays || sym->attr.target)
1258 {
1259 if (as->type == AS_ASSUMED_SIZE)
1260 packed = PACKED_FULL;
1261 }
1262 else
1263 {
1264 if (as->type == AS_EXPLICIT)
1265 {
1266 packed = PACKED_FULL;
1267 for (n = 0; n < as->rank; n++)
1268 {
1269 if (!(as->upper[n]
1270 && as->lower[n]
1271 && as->upper[n]->expr_type == EXPR_CONSTANT
1272 && as->lower[n]->expr_type == EXPR_CONSTANT))
1273 {
1274 packed = PACKED_PARTIAL;
1275 break;
1276 }
1277 }
1278 }
1279 else
1280 packed = PACKED_PARTIAL;
1281 }
1282
1283 /* For classarrays the element type is required, but
1284 gfc_typenode_for_spec () returns the array descriptor. */
1285 type = is_classarray ? gfc_get_element_type (type)
1286 : gfc_typenode_for_spec (&sym->ts);
1287 type = gfc_get_nodesc_array_type (type, as, packed,
1288 !sym->attr.target);
1289 }
1290 else
1291 {
1292 /* We now have an expression for the element size, so create a fully
1293 qualified type. Reset sym->backend decl or this will just return the
1294 old type. */
1295 DECL_ARTIFICIAL (sym->backend_decl) = 1;
1296 sym->backend_decl = NULL_TREE;
1297 type = gfc_sym_type (sym);
1298 packed = PACKED_FULL;
1299 }
1300
1301 ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0);
1302 decl = build_decl (input_location,
1303 VAR_DECL, get_identifier (name), type);
1304
1305 DECL_ARTIFICIAL (decl) = 1;
1306 DECL_NAMELESS (decl) = 1;
1307 TREE_PUBLIC (decl) = 0;
1308 TREE_STATIC (decl) = 0;
1309 DECL_EXTERNAL (decl) = 0;
1310
1311 /* Avoid uninitialized warnings for optional dummy arguments. */
1312 if ((sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.optional)
1313 || sym->attr.optional)
1314 suppress_warning (decl);
1315
1316 /* We should never get deferred shape arrays here. We used to because of
1317 frontend bugs. */
1318 gcc_assert (as->type != AS_DEFERRED);
1319
1320 if (packed == PACKED_PARTIAL)
1321 GFC_DECL_PARTIAL_PACKED_ARRAY (decl) = 1;
1322 else if (packed == PACKED_FULL)
1323 GFC_DECL_PACKED_ARRAY (decl) = 1;
1324
1325 gfc_build_qualified_array (decl, sym);
1326
1327 if (DECL_LANG_SPECIFIC (dummy))
1328 DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (dummy);
1329 else
1330 gfc_allocate_lang_decl (decl);
1331
1332 GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
1333
1334 if (sym->ns->proc_name->backend_decl == current_function_decl
1335 || sym->attr.contained)
1336 gfc_add_decl_to_function (decl);
1337 else
1338 gfc_add_decl_to_parent_function (decl);
1339
1340 return decl;
1341}
1342
1343/* Return a constant or a variable to use as a string length. Does not
1344 add the decl to the current scope. */
1345
1346static tree
1347gfc_create_string_length (gfc_symbol * sym)
1348{
1349 gcc_assert (sym->ts.u.cl);
1350 gfc_conv_const_charlen (sym->ts.u.cl);
1351
1352 if (sym->ts.u.cl->backend_decl == NULL_TREE)
1353 {
1354 tree length;
1355 const char *name;
1356
1357 /* The string length variable shall be in static memory if it is either
1358 explicitly SAVED, a module variable or with -fno-automatic. Only
1359 relevant is "len=:" - otherwise, it is either a constant length or
1360 it is an automatic variable. */
1361 bool static_length = sym->attr.save
1362 || sym->ns->proc_name->attr.flavor == FL_MODULE
1363 || (flag_max_stack_var_size == 0
1364 && sym->ts.deferred && !sym->attr.dummy
1365 && !sym->attr.result && !sym->attr.function);
1366
1367 /* Also prefix the mangled name. We need to call GFC_PREFIX for static
1368 variables as some systems do not support the "." in the assembler name.
1369 For nonstatic variables, the "." does not appear in assembler. */
1370 if (static_length)
1371 {
1372 if (sym->module)
1373 name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
1374 sym->name);
1375 else
1376 name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
1377 }
1378 else if (sym->module)
1379 name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
1380 else
1381 name = gfc_get_string (".%s", sym->name);
1382
1383 length = build_decl (input_location,
1384 VAR_DECL, get_identifier (name),
1385 gfc_charlen_type_node);
1386 DECL_ARTIFICIAL (length) = 1;
1387 TREE_USED (length) = 1;
1388 if (sym->ns->proc_name->tlink != NULL)
1389 gfc_defer_symbol_init (sym);
1390
1391 sym->ts.u.cl->backend_decl = length;
1392
1393 if (static_length)
1394 TREE_STATIC (length) = 1;
1395
1396 if (sym->ns->proc_name->attr.flavor == FL_MODULE
1397 && (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used))
1398 TREE_PUBLIC (length) = 1;
1399 }
1400
1401 gcc_assert (sym->ts.u.cl->backend_decl != NULL_TREE);
1402 return sym->ts.u.cl->backend_decl;
1403}
1404
1405/* If a variable is assigned a label, we add another two auxiliary
1406 variables. */
1407
1408static void
1409gfc_add_assign_aux_vars (gfc_symbol * sym)
1410{
1411 tree addr;
1412 tree length;
1413 tree decl;
1414
1415 gcc_assert (sym->backend_decl);
1416
1417 decl = sym->backend_decl;
1418 gfc_allocate_lang_decl (decl);
1419 GFC_DECL_ASSIGN (decl) = 1;
1420 length = build_decl (input_location,
1421 VAR_DECL, create_tmp_var_name (sym->name),
1422 gfc_charlen_type_node);
1423 addr = build_decl (input_location,
1424 VAR_DECL, create_tmp_var_name (sym->name),
1425 pvoid_type_node);
1426 gfc_finish_var_decl (decl: length, sym);
1427 gfc_finish_var_decl (decl: addr, sym);
1428 /* STRING_LENGTH is also used as flag. Less than -1 means that
1429 ASSIGN_ADDR cannot be used. Equal -1 means that ASSIGN_ADDR is the
1430 target label's address. Otherwise, value is the length of a format string
1431 and ASSIGN_ADDR is its address. */
1432 if (TREE_STATIC (length))
1433 DECL_INITIAL (length) = build_int_cst (gfc_charlen_type_node, -2);
1434 else
1435 gfc_defer_symbol_init (sym);
1436
1437 GFC_DECL_STRING_LEN (decl) = length;
1438 GFC_DECL_ASSIGN_ADDR (decl) = addr;
1439}
1440
1441
1442static tree
1443add_attributes_to_decl (symbol_attribute sym_attr, tree list)
1444{
1445 unsigned id;
1446 tree attr;
1447
1448 for (id = 0; id < EXT_ATTR_NUM; id++)
1449 if (sym_attr.ext_attr & (1 << id) && ext_attr_list[id].middle_end_name)
1450 {
1451 attr = build_tree_list (
1452 get_identifier (ext_attr_list[id].middle_end_name),
1453 NULL_TREE);
1454 list = chainon (list, attr);
1455 }
1456
1457 tree clauses = NULL_TREE;
1458
1459 if (sym_attr.oacc_routine_lop != OACC_ROUTINE_LOP_NONE)
1460 {
1461 omp_clause_code code;
1462 switch (sym_attr.oacc_routine_lop)
1463 {
1464 case OACC_ROUTINE_LOP_GANG:
1465 code = OMP_CLAUSE_GANG;
1466 break;
1467 case OACC_ROUTINE_LOP_WORKER:
1468 code = OMP_CLAUSE_WORKER;
1469 break;
1470 case OACC_ROUTINE_LOP_VECTOR:
1471 code = OMP_CLAUSE_VECTOR;
1472 break;
1473 case OACC_ROUTINE_LOP_SEQ:
1474 code = OMP_CLAUSE_SEQ;
1475 break;
1476 case OACC_ROUTINE_LOP_NONE:
1477 case OACC_ROUTINE_LOP_ERROR:
1478 default:
1479 gcc_unreachable ();
1480 }
1481 tree c = build_omp_clause (UNKNOWN_LOCATION, code);
1482 OMP_CLAUSE_CHAIN (c) = clauses;
1483 clauses = c;
1484
1485 tree dims = oacc_build_routine_dims (clauses);
1486 list = oacc_replace_fn_attrib_attr (attribs: list, dims);
1487 }
1488
1489 if (sym_attr.oacc_routine_nohost)
1490 {
1491 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_NOHOST);
1492 OMP_CLAUSE_CHAIN (c) = clauses;
1493 clauses = c;
1494 }
1495
1496 if (sym_attr.omp_device_type != OMP_DEVICE_TYPE_UNSET)
1497 {
1498 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEVICE_TYPE);
1499 switch (sym_attr.omp_device_type)
1500 {
1501 case OMP_DEVICE_TYPE_HOST:
1502 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_HOST;
1503 break;
1504 case OMP_DEVICE_TYPE_NOHOST:
1505 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
1506 break;
1507 case OMP_DEVICE_TYPE_ANY:
1508 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_ANY;
1509 break;
1510 default:
1511 gcc_unreachable ();
1512 }
1513 OMP_CLAUSE_CHAIN (c) = clauses;
1514 clauses = c;
1515 }
1516
1517 if (sym_attr.omp_declare_target_link
1518 || sym_attr.oacc_declare_link)
1519 list = tree_cons (get_identifier ("omp declare target link"),
1520 clauses, list);
1521 else if (sym_attr.omp_declare_target
1522 || sym_attr.oacc_declare_create
1523 || sym_attr.oacc_declare_copyin
1524 || sym_attr.oacc_declare_deviceptr
1525 || sym_attr.oacc_declare_device_resident)
1526 list = tree_cons (get_identifier ("omp declare target"),
1527 clauses, list);
1528
1529 if (sym_attr.omp_declare_target_indirect)
1530 list = tree_cons (get_identifier ("omp declare target indirect"),
1531 clauses, list);
1532
1533 return list;
1534}
1535
1536
1537static void build_function_decl (gfc_symbol * sym, bool global);
1538
1539
1540/* Return the decl for a gfc_symbol, create it if it doesn't already
1541 exist. */
1542
1543tree
1544gfc_get_symbol_decl (gfc_symbol * sym)
1545{
1546 tree decl;
1547 tree length = NULL_TREE;
1548 tree attributes;
1549 int byref;
1550 bool intrinsic_array_parameter = false;
1551 bool fun_or_res;
1552
1553 gcc_assert (sym->attr.referenced
1554 || sym->attr.flavor == FL_PROCEDURE
1555 || sym->attr.use_assoc
1556 || sym->attr.used_in_submodule
1557 || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY
1558 || (sym->module && sym->attr.if_source != IFSRC_DECL
1559 && sym->backend_decl));
1560
1561 if (sym->attr.dummy && sym->ns->proc_name->attr.is_bind_c
1562 && is_CFI_desc (sym, NULL))
1563 {
1564 gcc_assert (sym->backend_decl && (sym->ts.type != BT_CHARACTER
1565 || sym->ts.u.cl->backend_decl));
1566 return sym->backend_decl;
1567 }
1568
1569 if (sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.function)
1570 byref = gfc_return_by_reference (sym->ns->proc_name);
1571 else
1572 byref = 0;
1573
1574 /* Make sure that the vtab for the declared type is completed. */
1575 if (sym->ts.type == BT_CLASS)
1576 {
1577 gfc_component *c = CLASS_DATA (sym);
1578 if (!c->ts.u.derived->backend_decl)
1579 {
1580 gfc_find_derived_vtab (c->ts.u.derived);
1581 gfc_get_derived_type (derived: sym->ts.u.derived);
1582 }
1583 }
1584
1585 /* PDT parameterized array components and string_lengths must have the
1586 'len' parameters substituted for the expressions appearing in the
1587 declaration of the entity and memory allocated/deallocated. */
1588 if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
1589 && sym->param_list != NULL
1590 && gfc_current_ns == sym->ns
1591 && !(sym->attr.use_assoc || sym->attr.dummy))
1592 gfc_defer_symbol_init (sym);
1593
1594 /* Dummy PDT 'len' parameters should be checked when they are explicit. */
1595 if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
1596 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1597 && sym->param_list != NULL
1598 && sym->attr.dummy)
1599 gfc_defer_symbol_init (sym);
1600
1601 /* All deferred character length procedures need to retain the backend
1602 decl, which is a pointer to the character length in the caller's
1603 namespace and to declare a local character length. */
1604 if (!byref && sym->attr.function
1605 && sym->ts.type == BT_CHARACTER
1606 && sym->ts.deferred
1607 && sym->ts.u.cl->passed_length == NULL
1608 && sym->ts.u.cl->backend_decl
1609 && TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
1610 {
1611 sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1612 gcc_assert (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)));
1613 sym->ts.u.cl->backend_decl = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1614 }
1615
1616 fun_or_res = byref && (sym->attr.result
1617 || (sym->attr.function && sym->ts.deferred));
1618 if ((sym->attr.dummy && ! sym->attr.function) || fun_or_res)
1619 {
1620 /* Return via extra parameter. */
1621 if (sym->attr.result && byref
1622 && !sym->backend_decl)
1623 {
1624 sym->backend_decl =
1625 DECL_ARGUMENTS (sym->ns->proc_name->backend_decl);
1626 /* For entry master function skip over the __entry
1627 argument. */
1628 if (sym->ns->proc_name->attr.entry_master)
1629 sym->backend_decl = DECL_CHAIN (sym->backend_decl);
1630 }
1631
1632 /* Dummy variables should already have been created. */
1633 gcc_assert (sym->backend_decl);
1634
1635 /* However, the string length of deferred arrays must be set. */
1636 if (sym->ts.type == BT_CHARACTER
1637 && sym->ts.deferred
1638 && sym->attr.dimension
1639 && sym->attr.allocatable)
1640 gfc_defer_symbol_init (sym);
1641
1642 if (sym->attr.pointer && sym->attr.dimension && sym->ts.type != BT_CLASS)
1643 GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
1644
1645 /* Create a character length variable. */
1646 if (sym->ts.type == BT_CHARACTER)
1647 {
1648 /* For a deferred dummy, make a new string length variable. */
1649 if (sym->ts.deferred
1650 &&
1651 (sym->ts.u.cl->passed_length == sym->ts.u.cl->backend_decl))
1652 sym->ts.u.cl->backend_decl = NULL_TREE;
1653
1654 if (sym->ts.deferred && byref)
1655 {
1656 /* The string length of a deferred char array is stored in the
1657 parameter at sym->ts.u.cl->backend_decl as a reference and
1658 marked as a result. Exempt this variable from generating a
1659 temporary for it. */
1660 if (sym->attr.result)
1661 {
1662 /* We need to insert a indirect ref for param decls. */
1663 if (sym->ts.u.cl->backend_decl
1664 && TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
1665 {
1666 sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1667 sym->ts.u.cl->backend_decl =
1668 build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1669 }
1670 }
1671 /* For all other parameters make sure, that they are copied so
1672 that the value and any modifications are local to the routine
1673 by generating a temporary variable. */
1674 else if (sym->attr.function
1675 && sym->ts.u.cl->passed_length == NULL
1676 && sym->ts.u.cl->backend_decl)
1677 {
1678 sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1679 if (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)))
1680 sym->ts.u.cl->backend_decl
1681 = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1682 else
1683 sym->ts.u.cl->backend_decl = NULL_TREE;
1684 }
1685 }
1686
1687 if (sym->ts.u.cl->backend_decl == NULL_TREE)
1688 length = gfc_create_string_length (sym);
1689 else
1690 length = sym->ts.u.cl->backend_decl;
1691 if (VAR_P (length) && DECL_FILE_SCOPE_P (length))
1692 {
1693 /* Add the string length to the same context as the symbol. */
1694 if (DECL_CONTEXT (length) == NULL_TREE)
1695 {
1696 if (sym->backend_decl == current_function_decl
1697 || (DECL_CONTEXT (sym->backend_decl)
1698 == current_function_decl))
1699 gfc_add_decl_to_function (decl: length);
1700 else
1701 gfc_add_decl_to_parent_function (decl: length);
1702 }
1703
1704 gcc_assert (sym->backend_decl == current_function_decl
1705 ? DECL_CONTEXT (length) == current_function_decl
1706 : (DECL_CONTEXT (sym->backend_decl)
1707 == DECL_CONTEXT (length)));
1708
1709 gfc_defer_symbol_init (sym);
1710 }
1711 }
1712
1713 /* Use a copy of the descriptor for dummy arrays. */
1714 if ((sym->attr.dimension || sym->attr.codimension)
1715 && !TREE_USED (sym->backend_decl))
1716 {
1717 decl = gfc_build_dummy_array_decl (sym, dummy: sym->backend_decl);
1718 /* Prevent the dummy from being detected as unused if it is copied. */
1719 if (sym->backend_decl != NULL && decl != sym->backend_decl)
1720 DECL_ARTIFICIAL (sym->backend_decl) = 1;
1721 sym->backend_decl = decl;
1722 }
1723
1724 /* Returning the descriptor for dummy class arrays is hazardous, because
1725 some caller is expecting an expression to apply the component refs to.
1726 Therefore the descriptor is only created and stored in
1727 sym->backend_decl's GFC_DECL_SAVED_DESCRIPTOR. The caller is then
1728 responsible to extract it from there, when the descriptor is
1729 desired. */
1730 if (IS_CLASS_ARRAY (sym)
1731 && (!DECL_LANG_SPECIFIC (sym->backend_decl)
1732 || !GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl)))
1733 {
1734 decl = gfc_build_dummy_array_decl (sym, dummy: sym->backend_decl);
1735 /* Prevent the dummy from being detected as unused if it is copied. */
1736 if (sym->backend_decl != NULL && decl != sym->backend_decl)
1737 DECL_ARTIFICIAL (sym->backend_decl) = 1;
1738 sym->backend_decl = decl;
1739 }
1740
1741 TREE_USED (sym->backend_decl) = 1;
1742 if (sym->attr.assign && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
1743 gfc_add_assign_aux_vars (sym);
1744
1745 if (sym->ts.type == BT_CLASS && sym->backend_decl)
1746 GFC_DECL_CLASS(sym->backend_decl) = 1;
1747
1748 return sym->backend_decl;
1749 }
1750
1751 if (sym->result == sym && sym->attr.assign
1752 && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
1753 gfc_add_assign_aux_vars (sym);
1754
1755 if (sym->backend_decl)
1756 return sym->backend_decl;
1757
1758 /* Special case for array-valued named constants from intrinsic
1759 procedures; those are inlined. */
1760 if (sym->attr.use_assoc && sym->attr.flavor == FL_PARAMETER
1761 && (sym->from_intmod == INTMOD_ISO_FORTRAN_ENV
1762 || sym->from_intmod == INTMOD_ISO_C_BINDING))
1763 intrinsic_array_parameter = true;
1764
1765 /* If use associated compilation, use the module
1766 declaration. */
1767 if ((sym->attr.flavor == FL_VARIABLE
1768 || sym->attr.flavor == FL_PARAMETER)
1769 && (sym->attr.use_assoc || sym->attr.used_in_submodule)
1770 && !intrinsic_array_parameter
1771 && sym->module
1772 && gfc_get_module_backend_decl (sym))
1773 {
1774 if (sym->ts.type == BT_CLASS && sym->backend_decl)
1775 GFC_DECL_CLASS(sym->backend_decl) = 1;
1776 return sym->backend_decl;
1777 }
1778
1779 if (sym->attr.flavor == FL_PROCEDURE)
1780 {
1781 /* Catch functions. Only used for actual parameters,
1782 procedure pointers and procptr initialization targets. */
1783 if (sym->attr.use_assoc
1784 || sym->attr.used_in_submodule
1785 || sym->attr.intrinsic
1786 || sym->attr.if_source != IFSRC_DECL)
1787 {
1788 decl = gfc_get_extern_function_decl (sym);
1789 }
1790 else
1791 {
1792 if (!sym->backend_decl)
1793 build_function_decl (sym, global: false);
1794 decl = sym->backend_decl;
1795 }
1796 return decl;
1797 }
1798
1799 if (sym->ts.type == BT_UNKNOWN)
1800 gfc_fatal_error ("%s at %L has no default type", sym->name,
1801 &sym->declared_at);
1802
1803 if (sym->attr.intrinsic)
1804 gfc_internal_error ("intrinsic variable which isn't a procedure");
1805
1806 /* Create string length decl first so that they can be used in the
1807 type declaration. For associate names, the target character
1808 length is used. Set 'length' to a constant so that if the
1809 string length is a variable, it is not finished a second time. */
1810 if (sym->ts.type == BT_CHARACTER)
1811 {
1812 if (sym->attr.associate_var
1813 && sym->ts.deferred
1814 && sym->assoc && sym->assoc->target
1815 && ((sym->assoc->target->expr_type == EXPR_VARIABLE
1816 && sym->assoc->target->symtree->n.sym->ts.type != BT_CHARACTER)
1817 || sym->assoc->target->expr_type != EXPR_VARIABLE))
1818 sym->ts.u.cl->backend_decl = NULL_TREE;
1819
1820 if (sym->attr.associate_var
1821 && sym->ts.u.cl->backend_decl
1822 && (VAR_P (sym->ts.u.cl->backend_decl)
1823 || TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL))
1824 length = gfc_index_zero_node;
1825 else
1826 length = gfc_create_string_length (sym);
1827 }
1828
1829 /* Create the decl for the variable. */
1830 decl = build_decl (gfc_get_location (&sym->declared_at),
1831 VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym));
1832
1833 /* Add attributes to variables. Functions are handled elsewhere. */
1834 attributes = add_attributes_to_decl (sym_attr: sym->attr, NULL_TREE);
1835 decl_attributes (&decl, attributes, 0);
1836 if (sym->ts.deferred && VAR_P (length))
1837 decl_attributes (&length, attributes, 0);
1838
1839 /* Symbols from modules should have their assembler names mangled.
1840 This is done here rather than in gfc_finish_var_decl because it
1841 is different for string length variables. */
1842 if (sym->module || sym->fn_result_spec)
1843 {
1844 gfc_set_decl_assembler_name (decl, name: gfc_sym_mangled_identifier (sym));
1845 if (sym->attr.use_assoc && !intrinsic_array_parameter)
1846 DECL_IGNORED_P (decl) = 1;
1847 }
1848
1849 if (sym->attr.select_type_temporary)
1850 {
1851 DECL_ARTIFICIAL (decl) = 1;
1852 DECL_IGNORED_P (decl) = 1;
1853 }
1854
1855 if (sym->attr.dimension || sym->attr.codimension)
1856 {
1857 /* Create variables to hold the non-constant bits of array info. */
1858 gfc_build_qualified_array (decl, sym);
1859
1860 if (sym->attr.contiguous
1861 || ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer))
1862 GFC_DECL_PACKED_ARRAY (decl) = 1;
1863 }
1864
1865 /* Remember this variable for allocation/cleanup. */
1866 if (sym->attr.dimension || sym->attr.allocatable || sym->attr.codimension
1867 || (sym->ts.type == BT_CLASS &&
1868 (CLASS_DATA (sym)->attr.dimension
1869 || CLASS_DATA (sym)->attr.allocatable))
1870 || (sym->ts.type == BT_DERIVED
1871 && (sym->ts.u.derived->attr.alloc_comp
1872 || (!sym->attr.pointer && !sym->attr.artificial && !sym->attr.save
1873 && !sym->ns->proc_name->attr.is_main_program
1874 && gfc_is_finalizable (sym->ts.u.derived, NULL))))
1875 /* This applies a derived type default initializer. */
1876 || (sym->ts.type == BT_DERIVED
1877 && sym->attr.save == SAVE_NONE
1878 && !sym->attr.data
1879 && !sym->attr.allocatable
1880 && (sym->value && !sym->ns->proc_name->attr.is_main_program)
1881 && !(sym->attr.use_assoc && !intrinsic_array_parameter)))
1882 gfc_defer_symbol_init (sym);
1883
1884 /* Set the vptr of unlimited polymorphic pointer variables so that
1885 they do not cause segfaults in select type, when the selector
1886 is an intrinsic type. Arrays are captured above. */
1887 if (sym->ts.type == BT_CLASS && UNLIMITED_POLY (sym)
1888 && CLASS_DATA (sym)->attr.class_pointer
1889 && !CLASS_DATA (sym)->attr.dimension && !sym->attr.dummy
1890 && sym->attr.flavor == FL_VARIABLE && !sym->assoc)
1891 gfc_defer_symbol_init (sym);
1892
1893 if (sym->ts.type == BT_CHARACTER
1894 && sym->attr.allocatable
1895 && !sym->attr.dimension
1896 && sym->ts.u.cl && sym->ts.u.cl->length
1897 && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE)
1898 gfc_defer_symbol_init (sym);
1899
1900 /* Associate names can use the hidden string length variable
1901 of their associated target. */
1902 if (sym->ts.type == BT_CHARACTER
1903 && TREE_CODE (length) != INTEGER_CST
1904 && TREE_CODE (sym->ts.u.cl->backend_decl) != INDIRECT_REF)
1905 {
1906 length = fold_convert (gfc_charlen_type_node, length);
1907 gfc_finish_var_decl (decl: length, sym);
1908 if (!sym->attr.associate_var
1909 && VAR_P (length)
1910 && sym->value && sym->value->expr_type != EXPR_NULL
1911 && sym->value->ts.u.cl->length)
1912 {
1913 gfc_expr *len = sym->value->ts.u.cl->length;
1914 DECL_INITIAL (length) = gfc_conv_initializer (len, &len->ts,
1915 TREE_TYPE (length),
1916 false, false, false);
1917 DECL_INITIAL (length) = fold_convert (gfc_charlen_type_node,
1918 DECL_INITIAL (length));
1919 }
1920 else
1921 gcc_assert (!sym->value || sym->value->expr_type == EXPR_NULL);
1922 }
1923
1924 gfc_finish_var_decl (decl, sym);
1925
1926 if (sym->ts.type == BT_CHARACTER)
1927 /* Character variables need special handling. */
1928 gfc_allocate_lang_decl (decl);
1929
1930 if (sym->assoc && sym->attr.subref_array_pointer)
1931 sym->attr.pointer = 1;
1932
1933 if (sym->attr.pointer && sym->attr.dimension
1934 && !sym->ts.deferred
1935 && !(sym->attr.select_type_temporary
1936 && !sym->attr.subref_array_pointer))
1937 GFC_DECL_PTR_ARRAY_P (decl) = 1;
1938
1939 if (sym->ts.type == BT_CLASS)
1940 GFC_DECL_CLASS(decl) = 1;
1941
1942 sym->backend_decl = decl;
1943
1944 if (sym->attr.assign)
1945 gfc_add_assign_aux_vars (sym);
1946
1947 if (intrinsic_array_parameter)
1948 {
1949 TREE_STATIC (decl) = 1;
1950 DECL_EXTERNAL (decl) = 0;
1951 }
1952
1953 if (TREE_STATIC (decl)
1954 && !(sym->attr.use_assoc && !intrinsic_array_parameter)
1955 && (sym->attr.save || sym->ns->proc_name->attr.is_main_program
1956 || !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
1957 || sym->attr.data || sym->ns->proc_name->attr.flavor == FL_MODULE)
1958 && (flag_coarray != GFC_FCOARRAY_LIB
1959 || !sym->attr.codimension || sym->attr.allocatable)
1960 && !(sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
1961 && !(sym->ts.type == BT_CLASS
1962 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type))
1963 {
1964 /* Add static initializer. For procedures, it is only needed if
1965 SAVE is specified otherwise they need to be reinitialized
1966 every time the procedure is entered. The TREE_STATIC is
1967 in this case due to -fmax-stack-var-size=. */
1968
1969 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
1970 TREE_TYPE (decl), sym->attr.dimension
1971 || (sym->attr.codimension
1972 && sym->attr.allocatable),
1973 sym->attr.pointer || sym->attr.allocatable
1974 || sym->ts.type == BT_CLASS,
1975 sym->attr.proc_pointer);
1976 }
1977
1978 if (!TREE_STATIC (decl)
1979 && POINTER_TYPE_P (TREE_TYPE (decl))
1980 && !sym->attr.pointer
1981 && !sym->attr.allocatable
1982 && !sym->attr.proc_pointer
1983 && !sym->attr.select_type_temporary)
1984 DECL_BY_REFERENCE (decl) = 1;
1985
1986 if (sym->attr.associate_var)
1987 GFC_DECL_ASSOCIATE_VAR_P (decl) = 1;
1988
1989 /* We only longer mark __def_init as read-only if it actually has an
1990 initializer, it does not needlessly take up space in the
1991 read-only section and can go into the BSS instead, see PR 84487.
1992 Marking this as artificial means that OpenMP will treat this as
1993 predetermined shared. */
1994
1995 bool def_init = startswith (str: sym->name, prefix: "__def_init");
1996
1997 if (sym->attr.vtab || def_init)
1998 {
1999 DECL_ARTIFICIAL (decl) = 1;
2000 if (def_init && sym->value)
2001 TREE_READONLY (decl) = 1;
2002 }
2003
2004 return decl;
2005}
2006
2007
2008/* Substitute a temporary variable in place of the real one. */
2009
2010void
2011gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save)
2012{
2013 save->attr = sym->attr;
2014 save->decl = sym->backend_decl;
2015
2016 gfc_clear_attr (&sym->attr);
2017 sym->attr.referenced = 1;
2018 sym->attr.flavor = FL_VARIABLE;
2019
2020 sym->backend_decl = decl;
2021}
2022
2023
2024/* Restore the original variable. */
2025
2026void
2027gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
2028{
2029 sym->attr = save->attr;
2030 sym->backend_decl = save->decl;
2031}
2032
2033
2034/* Declare a procedure pointer. */
2035
2036static tree
2037get_proc_pointer_decl (gfc_symbol *sym)
2038{
2039 tree decl;
2040 tree attributes;
2041
2042 if (sym->module || sym->fn_result_spec)
2043 {
2044 const char *name;
2045 gfc_gsymbol *gsym;
2046
2047 name = mangled_identifier (sym);
2048 gsym = gfc_find_gsymbol (gfc_gsym_root, name);
2049 if (gsym != NULL)
2050 {
2051 gfc_symbol *s;
2052 gfc_find_symbol (sym->name, gsym->ns, 0, &s);
2053 if (s && s->backend_decl)
2054 return s->backend_decl;
2055 }
2056 }
2057
2058 decl = sym->backend_decl;
2059 if (decl)
2060 return decl;
2061
2062 decl = build_decl (input_location,
2063 VAR_DECL, get_identifier (sym->name),
2064 build_pointer_type (gfc_get_function_type (sym)));
2065
2066 if (sym->module)
2067 {
2068 /* Apply name mangling. */
2069 gfc_set_decl_assembler_name (decl, name: gfc_sym_mangled_identifier (sym));
2070 if (sym->attr.use_assoc)
2071 DECL_IGNORED_P (decl) = 1;
2072 }
2073
2074 if ((sym->ns->proc_name
2075 && sym->ns->proc_name->backend_decl == current_function_decl)
2076 || sym->attr.contained)
2077 gfc_add_decl_to_function (decl);
2078 else if (sym->ns->proc_name->attr.flavor != FL_MODULE)
2079 gfc_add_decl_to_parent_function (decl);
2080
2081 sym->backend_decl = decl;
2082
2083 /* If a variable is USE associated, it's always external. */
2084 if (sym->attr.use_assoc)
2085 {
2086 DECL_EXTERNAL (decl) = 1;
2087 TREE_PUBLIC (decl) = 1;
2088 }
2089 else if (sym->module && sym->ns->proc_name->attr.flavor == FL_MODULE)
2090 {
2091 /* This is the declaration of a module variable. */
2092 TREE_PUBLIC (decl) = 1;
2093 if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
2094 {
2095 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
2096 DECL_VISIBILITY_SPECIFIED (decl) = true;
2097 }
2098 TREE_STATIC (decl) = 1;
2099 }
2100
2101 if (!sym->attr.use_assoc
2102 && (sym->attr.save != SAVE_NONE || sym->attr.data
2103 || (sym->value && sym->ns->proc_name->attr.is_main_program)))
2104 TREE_STATIC (decl) = 1;
2105
2106 if (TREE_STATIC (decl) && sym->value)
2107 {
2108 /* Add static initializer. */
2109 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
2110 TREE_TYPE (decl),
2111 sym->attr.dimension,
2112 false, true);
2113 }
2114
2115 /* Handle threadprivate procedure pointers. */
2116 if (sym->attr.threadprivate
2117 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
2118 set_decl_tls_model (decl, decl_default_tls_model (decl));
2119
2120 attributes = add_attributes_to_decl (sym_attr: sym->attr, NULL_TREE);
2121 decl_attributes (&decl, attributes, 0);
2122
2123 return decl;
2124}
2125
2126
2127/* Get a basic decl for an external function. */
2128
2129tree
2130gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args,
2131 const char *fnspec)
2132{
2133 tree type;
2134 tree fndecl;
2135 tree attributes;
2136 gfc_expr e;
2137 gfc_intrinsic_sym *isym;
2138 gfc_expr argexpr;
2139 char s[GFC_MAX_SYMBOL_LEN + 23]; /* "_gfortran_f2c_specific" and '\0'. */
2140 tree name;
2141 tree mangled_name;
2142 gfc_gsymbol *gsym;
2143
2144 if (sym->backend_decl)
2145 return sym->backend_decl;
2146
2147 /* We should never be creating external decls for alternate entry points.
2148 The procedure may be an alternate entry point, but we don't want/need
2149 to know that. */
2150 gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
2151
2152 if (sym->attr.proc_pointer)
2153 return get_proc_pointer_decl (sym);
2154
2155 /* See if this is an external procedure from the same file. If so,
2156 return the backend_decl. If we are looking at a BIND(C)
2157 procedure and the symbol is not BIND(C), or vice versa, we
2158 haven't found the right procedure. */
2159
2160 if (sym->binding_label)
2161 {
2162 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->binding_label);
2163 if (gsym && !gsym->bind_c)
2164 gsym = NULL;
2165 }
2166 else if (sym->module == NULL)
2167 {
2168 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
2169 if (gsym && gsym->bind_c)
2170 gsym = NULL;
2171 }
2172 else
2173 {
2174 /* Procedure from a different module. */
2175 gsym = NULL;
2176 }
2177
2178 if (gsym && !gsym->defined)
2179 gsym = NULL;
2180
2181 /* This can happen because of C binding. */
2182 if (gsym && gsym->ns && gsym->ns->proc_name
2183 && gsym->ns->proc_name->attr.flavor == FL_MODULE)
2184 goto module_sym;
2185
2186 if ((!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL)
2187 && !sym->backend_decl
2188 && gsym && gsym->ns
2189 && ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION))
2190 && (gsym->ns->proc_name->backend_decl || !sym->attr.intrinsic))
2191 {
2192 if (!gsym->ns->proc_name->backend_decl)
2193 {
2194 /* By construction, the external function cannot be
2195 a contained procedure. */
2196 locus old_loc;
2197
2198 gfc_save_backend_locus (&old_loc);
2199 push_cfun (NULL);
2200
2201 gfc_create_function_decl (gsym->ns, true);
2202
2203 pop_cfun ();
2204 gfc_restore_backend_locus (&old_loc);
2205 }
2206
2207 /* If the namespace has entries, the proc_name is the
2208 entry master. Find the entry and use its backend_decl.
2209 otherwise, use the proc_name backend_decl. */
2210 if (gsym->ns->entries)
2211 {
2212 gfc_entry_list *entry = gsym->ns->entries;
2213
2214 for (; entry; entry = entry->next)
2215 {
2216 if (strcmp (s1: gsym->name, s2: entry->sym->name) == 0)
2217 {
2218 sym->backend_decl = entry->sym->backend_decl;
2219 break;
2220 }
2221 }
2222 }
2223 else
2224 sym->backend_decl = gsym->ns->proc_name->backend_decl;
2225
2226 if (sym->backend_decl)
2227 {
2228 /* Avoid problems of double deallocation of the backend declaration
2229 later in gfc_trans_use_stmts; cf. PR 45087. */
2230 if (sym->attr.if_source != IFSRC_DECL && sym->attr.use_assoc)
2231 sym->attr.use_assoc = 0;
2232
2233 return sym->backend_decl;
2234 }
2235 }
2236
2237 /* See if this is a module procedure from the same file. If so,
2238 return the backend_decl. */
2239 if (sym->module)
2240 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module);
2241
2242module_sym:
2243 if (gsym && gsym->ns
2244 && (gsym->type == GSYM_MODULE
2245 || (gsym->ns->proc_name && gsym->ns->proc_name->attr.flavor == FL_MODULE)))
2246 {
2247 gfc_symbol *s;
2248
2249 s = NULL;
2250 if (gsym->type == GSYM_MODULE)
2251 gfc_find_symbol (sym->name, gsym->ns, 0, &s);
2252 else
2253 gfc_find_symbol (gsym->sym_name, gsym->ns, 0, &s);
2254
2255 if (s && s->backend_decl)
2256 {
2257 if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
2258 gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
2259 true);
2260 else if (sym->ts.type == BT_CHARACTER)
2261 sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
2262 sym->backend_decl = s->backend_decl;
2263 return sym->backend_decl;
2264 }
2265 }
2266
2267 if (sym->attr.intrinsic)
2268 {
2269 /* Call the resolution function to get the actual name. This is
2270 a nasty hack which relies on the resolution functions only looking
2271 at the first argument. We pass NULL for the second argument
2272 otherwise things like AINT get confused. */
2273 isym = gfc_find_function (sym->name);
2274 gcc_assert (isym->resolve.f0 != NULL);
2275
2276 memset (s: &e, c: 0, n: sizeof (e));
2277 e.expr_type = EXPR_FUNCTION;
2278
2279 memset (s: &argexpr, c: 0, n: sizeof (argexpr));
2280 gcc_assert (isym->formal);
2281 argexpr.ts = isym->formal->ts;
2282
2283 if (isym->formal->next == NULL)
2284 isym->resolve.f1 (&e, &argexpr);
2285 else
2286 {
2287 if (isym->formal->next->next == NULL)
2288 isym->resolve.f2 (&e, &argexpr, NULL);
2289 else
2290 {
2291 if (isym->formal->next->next->next == NULL)
2292 isym->resolve.f3 (&e, &argexpr, NULL, NULL);
2293 else
2294 {
2295 /* All specific intrinsics take less than 5 arguments. */
2296 gcc_assert (isym->formal->next->next->next->next == NULL);
2297 isym->resolve.f4 (&e, &argexpr, NULL, NULL, NULL);
2298 }
2299 }
2300 }
2301
2302 if (flag_f2c
2303 && ((e.ts.type == BT_REAL && e.ts.kind == gfc_default_real_kind)
2304 || e.ts.type == BT_COMPLEX))
2305 {
2306 /* Specific which needs a different implementation if f2c
2307 calling conventions are used. */
2308 sprintf (s: s, format: "_gfortran_f2c_specific%s", e.value.function.name);
2309 }
2310 else
2311 sprintf (s: s, format: "_gfortran_specific%s", e.value.function.name);
2312
2313 name = get_identifier (s);
2314 mangled_name = name;
2315 }
2316 else
2317 {
2318 name = gfc_sym_identifier (sym);
2319 mangled_name = gfc_sym_mangled_function_id (sym);
2320 }
2321
2322 type = gfc_get_function_type (sym, args: actual_args, fnspec);
2323
2324 fndecl = build_decl (input_location,
2325 FUNCTION_DECL, name, type);
2326
2327 /* Initialize DECL_EXTERNAL and TREE_PUBLIC before calling decl_attributes;
2328 TREE_PUBLIC specifies whether a function is globally addressable (i.e.
2329 the opposite of declaring a function as static in C). */
2330 DECL_EXTERNAL (fndecl) = 1;
2331 TREE_PUBLIC (fndecl) = 1;
2332
2333 attributes = add_attributes_to_decl (sym_attr: sym->attr, NULL_TREE);
2334 decl_attributes (&fndecl, attributes, 0);
2335
2336 gfc_set_decl_assembler_name (decl: fndecl, name: mangled_name);
2337
2338 /* Set the context of this decl. */
2339 if (0 && sym->ns && sym->ns->proc_name)
2340 {
2341 /* TODO: Add external decls to the appropriate scope. */
2342 DECL_CONTEXT (fndecl) = sym->ns->proc_name->backend_decl;
2343 }
2344 else
2345 {
2346 /* Global declaration, e.g. intrinsic subroutine. */
2347 DECL_CONTEXT (fndecl) = NULL_TREE;
2348 }
2349
2350 /* Set attributes for PURE functions. A call to PURE function in the
2351 Fortran 95 sense is both pure and without side effects in the C
2352 sense. */
2353 if (sym->attr.pure || sym->attr.implicit_pure)
2354 {
2355 if (sym->attr.function && !gfc_return_by_reference (sym))
2356 DECL_PURE_P (fndecl) = 1;
2357 /* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
2358 parameters and don't use alternate returns (is this
2359 allowed?). In that case, calls to them are meaningless, and
2360 can be optimized away. See also in build_function_decl(). */
2361 TREE_SIDE_EFFECTS (fndecl) = 0;
2362 }
2363
2364 /* Mark non-returning functions. */
2365 if (sym->attr.noreturn || sym->attr.ext_attr & (1 << EXT_ATTR_NORETURN))
2366 TREE_THIS_VOLATILE(fndecl) = 1;
2367
2368 sym->backend_decl = fndecl;
2369
2370 if (DECL_CONTEXT (fndecl) == NULL_TREE)
2371 pushdecl_top_level (fndecl);
2372
2373 if (sym->formal_ns
2374 && sym->formal_ns->proc_name == sym)
2375 {
2376 if (sym->formal_ns->omp_declare_simd)
2377 gfc_trans_omp_declare_simd (sym->formal_ns);
2378 if (flag_openmp)
2379 gfc_trans_omp_declare_variant (sym->formal_ns);
2380 }
2381
2382 return fndecl;
2383}
2384
2385
2386/* Create a declaration for a procedure. For external functions (in the C
2387 sense) use gfc_get_extern_function_decl. HAS_ENTRIES is true if this is
2388 a master function with alternate entry points. */
2389
2390static void
2391build_function_decl (gfc_symbol * sym, bool global)
2392{
2393 tree fndecl, type, attributes;
2394 symbol_attribute attr;
2395 tree result_decl;
2396 gfc_formal_arglist *f;
2397
2398 bool module_procedure = sym->attr.module_procedure
2399 && sym->ns
2400 && sym->ns->proc_name
2401 && sym->ns->proc_name->attr.flavor == FL_MODULE;
2402
2403 gcc_assert (!sym->attr.external || module_procedure);
2404
2405 if (sym->backend_decl)
2406 return;
2407
2408 /* Set the line and filename. sym->declared_at seems to point to the
2409 last statement for subroutines, but it'll do for now. */
2410 gfc_set_backend_locus (&sym->declared_at);
2411
2412 /* Allow only one nesting level. Allow public declarations. */
2413 gcc_assert (current_function_decl == NULL_TREE
2414 || DECL_FILE_SCOPE_P (current_function_decl)
2415 || (TREE_CODE (DECL_CONTEXT (current_function_decl))
2416 == NAMESPACE_DECL));
2417
2418 type = gfc_get_function_type (sym);
2419 fndecl = build_decl (input_location,
2420 FUNCTION_DECL, gfc_sym_identifier (sym), type);
2421
2422 attr = sym->attr;
2423
2424 /* Initialize DECL_EXTERNAL and TREE_PUBLIC before calling decl_attributes;
2425 TREE_PUBLIC specifies whether a function is globally addressable (i.e.
2426 the opposite of declaring a function as static in C). */
2427 DECL_EXTERNAL (fndecl) = 0;
2428
2429 if (sym->attr.access == ACCESS_UNKNOWN && sym->module
2430 && (sym->ns->default_access == ACCESS_PRIVATE
2431 || (sym->ns->default_access == ACCESS_UNKNOWN
2432 && flag_module_private)))
2433 sym->attr.access = ACCESS_PRIVATE;
2434
2435 if (!current_function_decl
2436 && !sym->attr.entry_master && !sym->attr.is_main_program
2437 && (sym->attr.access != ACCESS_PRIVATE || sym->binding_label
2438 || sym->attr.public_used))
2439 TREE_PUBLIC (fndecl) = 1;
2440
2441 if (sym->attr.referenced || sym->attr.entry_master)
2442 TREE_USED (fndecl) = 1;
2443
2444 attributes = add_attributes_to_decl (sym_attr: attr, NULL_TREE);
2445 decl_attributes (&fndecl, attributes, 0);
2446
2447 /* Figure out the return type of the declared function, and build a
2448 RESULT_DECL for it. If this is a subroutine with alternate
2449 returns, build a RESULT_DECL for it. */
2450 result_decl = NULL_TREE;
2451 /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */
2452 if (attr.function)
2453 {
2454 if (gfc_return_by_reference (sym))
2455 type = void_type_node;
2456 else
2457 {
2458 if (sym->result != sym)
2459 result_decl = gfc_sym_identifier (sym: sym->result);
2460
2461 type = TREE_TYPE (TREE_TYPE (fndecl));
2462 }
2463 }
2464 else
2465 {
2466 /* Look for alternate return placeholders. */
2467 int has_alternate_returns = 0;
2468 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2469 {
2470 if (f->sym == NULL)
2471 {
2472 has_alternate_returns = 1;
2473 break;
2474 }
2475 }
2476
2477 if (has_alternate_returns)
2478 type = integer_type_node;
2479 else
2480 type = void_type_node;
2481 }
2482
2483 result_decl = build_decl (input_location,
2484 RESULT_DECL, result_decl, type);
2485 DECL_ARTIFICIAL (result_decl) = 1;
2486 DECL_IGNORED_P (result_decl) = 1;
2487 DECL_CONTEXT (result_decl) = fndecl;
2488 DECL_RESULT (fndecl) = result_decl;
2489
2490 /* Don't call layout_decl for a RESULT_DECL.
2491 layout_decl (result_decl, 0); */
2492
2493 /* TREE_STATIC means the function body is defined here. */
2494 TREE_STATIC (fndecl) = 1;
2495
2496 /* Set attributes for PURE functions. A call to a PURE function in the
2497 Fortran 95 sense is both pure and without side effects in the C
2498 sense. */
2499 if (attr.pure || attr.implicit_pure)
2500 {
2501 /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments
2502 including an alternate return. In that case it can also be
2503 marked as PURE. See also in gfc_get_extern_function_decl(). */
2504 if (attr.function && !gfc_return_by_reference (sym))
2505 DECL_PURE_P (fndecl) = 1;
2506 TREE_SIDE_EFFECTS (fndecl) = 0;
2507 }
2508
2509 /* Mark noinline functions. */
2510 if (attr.ext_attr & (1 << EXT_ATTR_NOINLINE))
2511 DECL_UNINLINABLE (fndecl) = 1;
2512
2513 /* Mark noreturn functions. */
2514 if (attr.ext_attr & (1 << EXT_ATTR_NORETURN))
2515 TREE_THIS_VOLATILE (fndecl) = 1;
2516
2517 /* Mark weak functions. */
2518 if (attr.ext_attr & (1 << EXT_ATTR_WEAK))
2519 declare_weak (fndecl);
2520
2521 /* Layout the function declaration and put it in the binding level
2522 of the current function. */
2523
2524 if (global)
2525 pushdecl_top_level (fndecl);
2526 else
2527 pushdecl (fndecl);
2528
2529 /* Perform name mangling if this is a top level or module procedure. */
2530 if (current_function_decl == NULL_TREE)
2531 gfc_set_decl_assembler_name (decl: fndecl, name: gfc_sym_mangled_function_id (sym));
2532
2533 sym->backend_decl = fndecl;
2534}
2535
2536
2537/* Create the DECL_ARGUMENTS for a procedure.
2538 NOTE: The arguments added here must match the argument type created by
2539 gfc_get_function_type (). */
2540
2541static void
2542create_function_arglist (gfc_symbol * sym)
2543{
2544 tree fndecl;
2545 gfc_formal_arglist *f;
2546 tree typelist, hidden_typelist, optval_typelist;
2547 tree arglist, hidden_arglist, optval_arglist;
2548 tree type;
2549 tree parm;
2550
2551 fndecl = sym->backend_decl;
2552
2553 /* Build formal argument list. Make sure that their TREE_CONTEXT is
2554 the new FUNCTION_DECL node. */
2555 arglist = NULL_TREE;
2556 hidden_arglist = NULL_TREE;
2557 optval_arglist = NULL_TREE;
2558 typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2559
2560 if (sym->attr.entry_master)
2561 {
2562 type = TREE_VALUE (typelist);
2563 parm = build_decl (input_location,
2564 PARM_DECL, get_identifier ("__entry"), type);
2565
2566 DECL_CONTEXT (parm) = fndecl;
2567 DECL_ARG_TYPE (parm) = type;
2568 TREE_READONLY (parm) = 1;
2569 gfc_finish_decl (decl: parm);
2570 DECL_ARTIFICIAL (parm) = 1;
2571
2572 arglist = chainon (arglist, parm);
2573 typelist = TREE_CHAIN (typelist);
2574 }
2575
2576 if (gfc_return_by_reference (sym))
2577 {
2578 tree type = TREE_VALUE (typelist), length = NULL;
2579
2580 if (sym->ts.type == BT_CHARACTER)
2581 {
2582 /* Length of character result. */
2583 tree len_type = TREE_VALUE (TREE_CHAIN (typelist));
2584
2585 length = build_decl (input_location,
2586 PARM_DECL,
2587 get_identifier (".__result"),
2588 len_type);
2589 if (POINTER_TYPE_P (len_type))
2590 {
2591 sym->ts.u.cl->passed_length = length;
2592 TREE_USED (length) = 1;
2593 }
2594 else if (!sym->ts.u.cl->length)
2595 {
2596 sym->ts.u.cl->backend_decl = length;
2597 TREE_USED (length) = 1;
2598 }
2599 gcc_assert (TREE_CODE (length) == PARM_DECL);
2600 DECL_CONTEXT (length) = fndecl;
2601 DECL_ARG_TYPE (length) = len_type;
2602 TREE_READONLY (length) = 1;
2603 DECL_ARTIFICIAL (length) = 1;
2604 gfc_finish_decl (decl: length);
2605 if (sym->ts.u.cl->backend_decl == NULL
2606 || sym->ts.u.cl->backend_decl == length)
2607 {
2608 gfc_symbol *arg;
2609 tree backend_decl;
2610
2611 if (sym->ts.u.cl->backend_decl == NULL)
2612 {
2613 tree len = build_decl (input_location,
2614 VAR_DECL,
2615 get_identifier ("..__result"),
2616 gfc_charlen_type_node);
2617 DECL_ARTIFICIAL (len) = 1;
2618 TREE_USED (len) = 1;
2619 sym->ts.u.cl->backend_decl = len;
2620 }
2621
2622 /* Make sure PARM_DECL type doesn't point to incomplete type. */
2623 arg = sym->result ? sym->result : sym;
2624 backend_decl = arg->backend_decl;
2625 /* Temporary clear it, so that gfc_sym_type creates complete
2626 type. */
2627 arg->backend_decl = NULL;
2628 type = gfc_sym_type (arg);
2629 arg->backend_decl = backend_decl;
2630 type = build_reference_type (type);
2631 }
2632 }
2633
2634 parm = build_decl (input_location,
2635 PARM_DECL, get_identifier ("__result"), type);
2636
2637 DECL_CONTEXT (parm) = fndecl;
2638 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
2639 TREE_READONLY (parm) = 1;
2640 DECL_ARTIFICIAL (parm) = 1;
2641 gfc_finish_decl (decl: parm);
2642
2643 arglist = chainon (arglist, parm);
2644 typelist = TREE_CHAIN (typelist);
2645
2646 if (sym->ts.type == BT_CHARACTER)
2647 {
2648 gfc_allocate_lang_decl (decl: parm);
2649 arglist = chainon (arglist, length);
2650 typelist = TREE_CHAIN (typelist);
2651 }
2652 }
2653
2654 hidden_typelist = typelist;
2655 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2656 if (f->sym != NULL) /* Ignore alternate returns. */
2657 hidden_typelist = TREE_CHAIN (hidden_typelist);
2658
2659 /* Advance hidden_typelist over optional+value argument presence flags. */
2660 optval_typelist = hidden_typelist;
2661 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2662 if (f->sym != NULL
2663 && f->sym->attr.optional && f->sym->attr.value
2664 && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
2665 && !gfc_bt_struct (f->sym->ts.type))
2666 hidden_typelist = TREE_CHAIN (hidden_typelist);
2667
2668 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2669 {
2670 char name[GFC_MAX_SYMBOL_LEN + 2];
2671
2672 /* Ignore alternate returns. */
2673 if (f->sym == NULL)
2674 continue;
2675
2676 type = TREE_VALUE (typelist);
2677
2678 if (f->sym->ts.type == BT_CHARACTER
2679 && (!sym->attr.is_bind_c || sym->attr.entry_master))
2680 {
2681 tree len_type = TREE_VALUE (hidden_typelist);
2682 tree length = NULL_TREE;
2683 if (!f->sym->ts.deferred)
2684 gcc_assert (len_type == gfc_charlen_type_node);
2685 else
2686 gcc_assert (POINTER_TYPE_P (len_type));
2687
2688 strcpy (dest: &name[1], src: f->sym->name);
2689 name[0] = '_';
2690 length = build_decl (input_location,
2691 PARM_DECL, get_identifier (name), len_type);
2692
2693 hidden_arglist = chainon (hidden_arglist, length);
2694 DECL_CONTEXT (length) = fndecl;
2695 DECL_ARTIFICIAL (length) = 1;
2696 DECL_ARG_TYPE (length) = len_type;
2697 TREE_READONLY (length) = 1;
2698 gfc_finish_decl (decl: length);
2699
2700 /* Marking the length DECL_HIDDEN_STRING_LENGTH will lead
2701 to tail calls being disabled. Only do that if we
2702 potentially have broken callers. */
2703 if (flag_tail_call_workaround
2704 && f->sym->ts.u.cl
2705 && f->sym->ts.u.cl->length
2706 && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
2707 && (flag_tail_call_workaround == 2
2708 || f->sym->ns->implicit_interface_calls))
2709 DECL_HIDDEN_STRING_LENGTH (length) = 1;
2710
2711 /* Remember the passed value. */
2712 if (!f->sym->ts.u.cl || f->sym->ts.u.cl->passed_length)
2713 {
2714 /* This can happen if the same type is used for multiple
2715 arguments. We need to copy cl as otherwise
2716 cl->passed_length gets overwritten. */
2717 f->sym->ts.u.cl = gfc_new_charlen (f->sym->ns, f->sym->ts.u.cl);
2718 }
2719 f->sym->ts.u.cl->passed_length = length;
2720
2721 /* Use the passed value for assumed length variables. */
2722 if (!f->sym->ts.u.cl->length)
2723 {
2724 TREE_USED (length) = 1;
2725 gcc_assert (!f->sym->ts.u.cl->backend_decl);
2726 f->sym->ts.u.cl->backend_decl = length;
2727 }
2728
2729 hidden_typelist = TREE_CHAIN (hidden_typelist);
2730
2731 if (f->sym->ts.u.cl->backend_decl == NULL
2732 || f->sym->ts.u.cl->backend_decl == length)
2733 {
2734 if (POINTER_TYPE_P (len_type))
2735 f->sym->ts.u.cl->backend_decl
2736 = build_fold_indirect_ref_loc (input_location, length);
2737 else if (f->sym->ts.u.cl->backend_decl == NULL)
2738 gfc_create_string_length (sym: f->sym);
2739
2740 /* Make sure PARM_DECL type doesn't point to incomplete type. */
2741 if (f->sym->attr.flavor == FL_PROCEDURE)
2742 type = build_pointer_type (gfc_get_function_type (f->sym));
2743 else
2744 type = gfc_sym_type (f->sym);
2745 }
2746 }
2747 /* For scalar intrinsic types, VALUE passes the value,
2748 hence, the optional status cannot be transferred via a NULL pointer.
2749 Thus, we will use a hidden argument in that case. */
2750 if (f->sym->attr.optional && f->sym->attr.value
2751 && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
2752 && !gfc_bt_struct (f->sym->ts.type))
2753 {
2754 tree tmp;
2755 strcpy (dest: &name[1], src: f->sym->name);
2756 name[0] = '.';
2757 tmp = build_decl (input_location,
2758 PARM_DECL, get_identifier (name),
2759 boolean_type_node);
2760
2761 optval_arglist = chainon (optval_arglist, tmp);
2762 DECL_CONTEXT (tmp) = fndecl;
2763 DECL_ARTIFICIAL (tmp) = 1;
2764 DECL_ARG_TYPE (tmp) = boolean_type_node;
2765 TREE_READONLY (tmp) = 1;
2766 gfc_finish_decl (decl: tmp);
2767
2768 /* The presence flag must be boolean. */
2769 gcc_assert (TREE_VALUE (optval_typelist) == boolean_type_node);
2770 optval_typelist = TREE_CHAIN (optval_typelist);
2771 }
2772
2773 /* For non-constant length array arguments, make sure they use
2774 a different type node from TYPE_ARG_TYPES type. */
2775 if (f->sym->attr.dimension
2776 && type == TREE_VALUE (typelist)
2777 && TREE_CODE (type) == POINTER_TYPE
2778 && GFC_ARRAY_TYPE_P (type)
2779 && f->sym->as->type != AS_ASSUMED_SIZE
2780 && ! COMPLETE_TYPE_P (TREE_TYPE (type)))
2781 {
2782 if (f->sym->attr.flavor == FL_PROCEDURE)
2783 type = build_pointer_type (gfc_get_function_type (f->sym));
2784 else
2785 type = gfc_sym_type (f->sym);
2786 }
2787
2788 if (f->sym->attr.proc_pointer)
2789 type = build_pointer_type (type);
2790
2791 if (f->sym->attr.volatile_)
2792 type = build_qualified_type (type, TYPE_QUAL_VOLATILE);
2793
2794 /* Build the argument declaration. For C descriptors, we use a
2795 '_'-prefixed name for the parm_decl and inside the proc the
2796 sym->name. */
2797 tree parm_name;
2798 if (sym->attr.is_bind_c && is_CFI_desc (f->sym, NULL))
2799 {
2800 strcpy (dest: &name[1], src: f->sym->name);
2801 name[0] = '_';
2802 parm_name = get_identifier (name);
2803 }
2804 else
2805 parm_name = gfc_sym_identifier (sym: f->sym);
2806 parm = build_decl (input_location, PARM_DECL, parm_name, type);
2807
2808 if (f->sym->attr.volatile_)
2809 {
2810 TREE_THIS_VOLATILE (parm) = 1;
2811 TREE_SIDE_EFFECTS (parm) = 1;
2812 }
2813
2814 /* Fill in arg stuff. */
2815 DECL_CONTEXT (parm) = fndecl;
2816 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
2817 /* All implementation args except for VALUE are read-only. */
2818 if (!f->sym->attr.value)
2819 TREE_READONLY (parm) = 1;
2820 if (POINTER_TYPE_P (type)
2821 && (!f->sym->attr.proc_pointer
2822 && f->sym->attr.flavor != FL_PROCEDURE))
2823 DECL_BY_REFERENCE (parm) = 1;
2824 if (f->sym->attr.optional)
2825 {
2826 gfc_allocate_lang_decl (decl: parm);
2827 GFC_DECL_OPTIONAL_ARGUMENT (parm) = 1;
2828 }
2829
2830 gfc_finish_decl (decl: parm);
2831 gfc_finish_decl_attrs (decl: parm, attr: &f->sym->attr);
2832
2833 f->sym->backend_decl = parm;
2834
2835 /* Coarrays which are descriptorless or assumed-shape pass with
2836 -fcoarray=lib the token and the offset as hidden arguments. */
2837 if (flag_coarray == GFC_FCOARRAY_LIB
2838 && ((f->sym->ts.type != BT_CLASS && f->sym->attr.codimension
2839 && !f->sym->attr.allocatable)
2840 || (f->sym->ts.type == BT_CLASS
2841 && CLASS_DATA (f->sym)->attr.codimension
2842 && !CLASS_DATA (f->sym)->attr.allocatable)))
2843 {
2844 tree caf_type;
2845 tree token;
2846 tree offset;
2847
2848 gcc_assert (f->sym->backend_decl != NULL_TREE
2849 && !sym->attr.is_bind_c);
2850 caf_type = f->sym->ts.type == BT_CLASS
2851 ? TREE_TYPE (CLASS_DATA (f->sym)->backend_decl)
2852 : TREE_TYPE (f->sym->backend_decl);
2853
2854 token = build_decl (input_location, PARM_DECL,
2855 create_tmp_var_name ("caf_token"),
2856 build_qualified_type (pvoid_type_node,
2857 TYPE_QUAL_RESTRICT));
2858 if ((f->sym->ts.type != BT_CLASS
2859 && f->sym->as->type != AS_DEFERRED)
2860 || (f->sym->ts.type == BT_CLASS
2861 && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
2862 {
2863 gcc_assert (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL
2864 || GFC_DECL_TOKEN (f->sym->backend_decl) == NULL_TREE);
2865 if (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL)
2866 gfc_allocate_lang_decl (decl: f->sym->backend_decl);
2867 GFC_DECL_TOKEN (f->sym->backend_decl) = token;
2868 }
2869 else
2870 {
2871 gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) == NULL_TREE);
2872 GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) = token;
2873 }
2874
2875 DECL_CONTEXT (token) = fndecl;
2876 DECL_ARTIFICIAL (token) = 1;
2877 DECL_ARG_TYPE (token) = TREE_VALUE (typelist);
2878 TREE_READONLY (token) = 1;
2879 hidden_arglist = chainon (hidden_arglist, token);
2880 hidden_typelist = TREE_CHAIN (hidden_typelist);
2881 gfc_finish_decl (decl: token);
2882
2883 offset = build_decl (input_location, PARM_DECL,
2884 create_tmp_var_name ("caf_offset"),
2885 gfc_array_index_type);
2886
2887 if ((f->sym->ts.type != BT_CLASS
2888 && f->sym->as->type != AS_DEFERRED)
2889 || (f->sym->ts.type == BT_CLASS
2890 && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
2891 {
2892 gcc_assert (GFC_DECL_CAF_OFFSET (f->sym->backend_decl)
2893 == NULL_TREE);
2894 GFC_DECL_CAF_OFFSET (f->sym->backend_decl) = offset;
2895 }
2896 else
2897 {
2898 gcc_assert (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) == NULL_TREE);
2899 GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) = offset;
2900 }
2901 DECL_CONTEXT (offset) = fndecl;
2902 DECL_ARTIFICIAL (offset) = 1;
2903 DECL_ARG_TYPE (offset) = TREE_VALUE (typelist);
2904 TREE_READONLY (offset) = 1;
2905 hidden_arglist = chainon (hidden_arglist, offset);
2906 hidden_typelist = TREE_CHAIN (hidden_typelist);
2907 gfc_finish_decl (decl: offset);
2908 }
2909
2910 arglist = chainon (arglist, parm);
2911 typelist = TREE_CHAIN (typelist);
2912 }
2913
2914 /* Add hidden present status for optional+value arguments. */
2915 arglist = chainon (arglist, optval_arglist);
2916
2917 /* Add the hidden string length parameters, unless the procedure
2918 is bind(C). */
2919 if (!sym->attr.is_bind_c)
2920 arglist = chainon (arglist, hidden_arglist);
2921
2922 gcc_assert (hidden_typelist == NULL_TREE
2923 || TREE_VALUE (hidden_typelist) == void_type_node);
2924 DECL_ARGUMENTS (fndecl) = arglist;
2925}
2926
2927/* Do the setup necessary before generating the body of a function. */
2928
2929static void
2930trans_function_start (gfc_symbol * sym)
2931{
2932 tree fndecl;
2933
2934 fndecl = sym->backend_decl;
2935
2936 /* Let GCC know the current scope is this function. */
2937 current_function_decl = fndecl;
2938
2939 /* Let the world know what we're about to do. */
2940 announce_function (fndecl);
2941
2942 if (DECL_FILE_SCOPE_P (fndecl))
2943 {
2944 /* Create RTL for function declaration. */
2945 rest_of_decl_compilation (fndecl, 1, 0);
2946 }
2947
2948 /* Create RTL for function definition. */
2949 make_decl_rtl (fndecl);
2950
2951 allocate_struct_function (fndecl, false);
2952
2953 /* function.cc requires a push at the start of the function. */
2954 pushlevel ();
2955}
2956
2957/* Create thunks for alternate entry points. */
2958
2959static void
2960build_entry_thunks (gfc_namespace * ns, bool global)
2961{
2962 gfc_formal_arglist *formal;
2963 gfc_formal_arglist *thunk_formal;
2964 gfc_entry_list *el;
2965 gfc_symbol *thunk_sym;
2966 stmtblock_t body;
2967 tree thunk_fndecl;
2968 tree tmp;
2969 locus old_loc;
2970
2971 /* This should always be a toplevel function. */
2972 gcc_assert (current_function_decl == NULL_TREE);
2973
2974 gfc_save_backend_locus (&old_loc);
2975 for (el = ns->entries; el; el = el->next)
2976 {
2977 vec<tree, va_gc> *args = NULL;
2978 vec<tree, va_gc> *string_args = NULL;
2979
2980 thunk_sym = el->sym;
2981
2982 build_function_decl (sym: thunk_sym, global);
2983 create_function_arglist (sym: thunk_sym);
2984
2985 trans_function_start (sym: thunk_sym);
2986
2987 thunk_fndecl = thunk_sym->backend_decl;
2988
2989 gfc_init_block (&body);
2990
2991 /* Pass extra parameter identifying this entry point. */
2992 tmp = build_int_cst (gfc_array_index_type, el->id);
2993 vec_safe_push (v&: args, obj: tmp);
2994
2995 if (thunk_sym->attr.function)
2996 {
2997 if (gfc_return_by_reference (ns->proc_name))
2998 {
2999 tree ref = DECL_ARGUMENTS (current_function_decl);
3000 vec_safe_push (v&: args, obj: ref);
3001 if (ns->proc_name->ts.type == BT_CHARACTER)
3002 vec_safe_push (v&: args, DECL_CHAIN (ref));
3003 }
3004 }
3005
3006 for (formal = gfc_sym_get_dummy_args (ns->proc_name); formal;
3007 formal = formal->next)
3008 {
3009 /* Ignore alternate returns. */
3010 if (formal->sym == NULL)
3011 continue;
3012
3013 /* We don't have a clever way of identifying arguments, so resort to
3014 a brute-force search. */
3015 for (thunk_formal = gfc_sym_get_dummy_args (thunk_sym);
3016 thunk_formal;
3017 thunk_formal = thunk_formal->next)
3018 {
3019 if (thunk_formal->sym == formal->sym)
3020 break;
3021 }
3022
3023 if (thunk_formal)
3024 {
3025 /* Pass the argument. */
3026 DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1;
3027 vec_safe_push (v&: args, obj: thunk_formal->sym->backend_decl);
3028 if (formal->sym->ts.type == BT_CHARACTER)
3029 {
3030 tmp = thunk_formal->sym->ts.u.cl->backend_decl;
3031 vec_safe_push (v&: string_args, obj: tmp);
3032 }
3033 }
3034 else
3035 {
3036 /* Pass NULL for a missing argument. */
3037 vec_safe_push (v&: args, null_pointer_node);
3038 if (formal->sym->ts.type == BT_CHARACTER)
3039 {
3040 tmp = build_int_cst (gfc_charlen_type_node, 0);
3041 vec_safe_push (v&: string_args, obj: tmp);
3042 }
3043 }
3044 }
3045
3046 /* Call the master function. */
3047 vec_safe_splice (dst&: args, src: string_args);
3048 tmp = ns->proc_name->backend_decl;
3049 tmp = build_call_expr_loc_vec (input_location, tmp, args);
3050 if (ns->proc_name->attr.mixed_entry_master)
3051 {
3052 tree union_decl, field;
3053 tree master_type = TREE_TYPE (ns->proc_name->backend_decl);
3054
3055 union_decl = build_decl (input_location,
3056 VAR_DECL, get_identifier ("__result"),
3057 TREE_TYPE (master_type));
3058 DECL_ARTIFICIAL (union_decl) = 1;
3059 DECL_EXTERNAL (union_decl) = 0;
3060 TREE_PUBLIC (union_decl) = 0;
3061 TREE_USED (union_decl) = 1;
3062 layout_decl (union_decl, 0);
3063 pushdecl (union_decl);
3064
3065 DECL_CONTEXT (union_decl) = current_function_decl;
3066 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3067 TREE_TYPE (union_decl), union_decl, tmp);
3068 gfc_add_expr_to_block (&body, tmp);
3069
3070 for (field = TYPE_FIELDS (TREE_TYPE (union_decl));
3071 field; field = DECL_CHAIN (field))
3072 if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
3073 s2: thunk_sym->result->name) == 0)
3074 break;
3075 gcc_assert (field != NULL_TREE);
3076 tmp = fold_build3_loc (input_location, COMPONENT_REF,
3077 TREE_TYPE (field), union_decl, field,
3078 NULL_TREE);
3079 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3080 TREE_TYPE (DECL_RESULT (current_function_decl)),
3081 DECL_RESULT (current_function_decl), tmp);
3082 tmp = build1_v (RETURN_EXPR, tmp);
3083 }
3084 else if (TREE_TYPE (DECL_RESULT (current_function_decl))
3085 != void_type_node)
3086 {
3087 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3088 TREE_TYPE (DECL_RESULT (current_function_decl)),
3089 DECL_RESULT (current_function_decl), tmp);
3090 tmp = build1_v (RETURN_EXPR, tmp);
3091 }
3092 gfc_add_expr_to_block (&body, tmp);
3093
3094 /* Finish off this function and send it for code generation. */
3095 DECL_SAVED_TREE (thunk_fndecl) = gfc_finish_block (&body);
3096 tmp = getdecls ();
3097 poplevel (1, 1);
3098 BLOCK_SUPERCONTEXT (DECL_INITIAL (thunk_fndecl)) = thunk_fndecl;
3099 DECL_SAVED_TREE (thunk_fndecl)
3100 = fold_build3_loc (DECL_SOURCE_LOCATION (thunk_fndecl), BIND_EXPR,
3101 void_type_node, tmp, DECL_SAVED_TREE (thunk_fndecl),
3102 DECL_INITIAL (thunk_fndecl));
3103
3104 /* Output the GENERIC tree. */
3105 dump_function (phase: TDI_original, fn: thunk_fndecl);
3106
3107 /* Store the end of the function, so that we get good line number
3108 info for the epilogue. */
3109 cfun->function_end_locus = input_location;
3110
3111 /* We're leaving the context of this function, so zap cfun.
3112 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
3113 tree_rest_of_compilation. */
3114 set_cfun (NULL);
3115
3116 current_function_decl = NULL_TREE;
3117
3118 cgraph_node::finalize_function (thunk_fndecl, true);
3119
3120 /* We share the symbols in the formal argument list with other entry
3121 points and the master function. Clear them so that they are
3122 recreated for each function. */
3123 for (formal = gfc_sym_get_dummy_args (thunk_sym); formal;
3124 formal = formal->next)
3125 if (formal->sym != NULL) /* Ignore alternate returns. */
3126 {
3127 formal->sym->backend_decl = NULL_TREE;
3128 if (formal->sym->ts.type == BT_CHARACTER)
3129 formal->sym->ts.u.cl->backend_decl = NULL_TREE;
3130 }
3131
3132 if (thunk_sym->attr.function)
3133 {
3134 if (thunk_sym->ts.type == BT_CHARACTER)
3135 thunk_sym->ts.u.cl->backend_decl = NULL_TREE;
3136 if (thunk_sym->result->ts.type == BT_CHARACTER)
3137 thunk_sym->result->ts.u.cl->backend_decl = NULL_TREE;
3138 }
3139 }
3140
3141 gfc_restore_backend_locus (&old_loc);
3142}
3143
3144
3145/* Create a decl for a function, and create any thunks for alternate entry
3146 points. If global is true, generate the function in the global binding
3147 level, otherwise in the current binding level (which can be global). */
3148
3149void
3150gfc_create_function_decl (gfc_namespace * ns, bool global)
3151{
3152 /* Create a declaration for the master function. */
3153 build_function_decl (sym: ns->proc_name, global);
3154
3155 /* Compile the entry thunks. */
3156 if (ns->entries)
3157 build_entry_thunks (ns, global);
3158
3159 /* Now create the read argument list. */
3160 create_function_arglist (sym: ns->proc_name);
3161
3162 if (ns->omp_declare_simd)
3163 gfc_trans_omp_declare_simd (ns);
3164
3165 /* Handle 'declare variant' directives. The applicable directives might
3166 be declared in a parent namespace, so this needs to be called even if
3167 there are no local directives. */
3168 if (flag_openmp)
3169 gfc_trans_omp_declare_variant (ns);
3170}
3171
3172/* Return the decl used to hold the function return value. If
3173 parent_flag is set, the context is the parent_scope. */
3174
3175tree
3176gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
3177{
3178 tree decl;
3179 tree length;
3180 tree this_fake_result_decl;
3181 tree this_function_decl;
3182
3183 char name[GFC_MAX_SYMBOL_LEN + 10];
3184
3185 if (parent_flag)
3186 {
3187 this_fake_result_decl = parent_fake_result_decl;
3188 this_function_decl = DECL_CONTEXT (current_function_decl);
3189 }
3190 else
3191 {
3192 this_fake_result_decl = current_fake_result_decl;
3193 this_function_decl = current_function_decl;
3194 }
3195
3196 if (sym
3197 && sym->ns->proc_name->backend_decl == this_function_decl
3198 && sym->ns->proc_name->attr.entry_master
3199 && sym != sym->ns->proc_name)
3200 {
3201 tree t = NULL, var;
3202 if (this_fake_result_decl != NULL)
3203 for (t = TREE_CHAIN (this_fake_result_decl); t; t = TREE_CHAIN (t))
3204 if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), s2: sym->name) == 0)
3205 break;
3206 if (t)
3207 return TREE_VALUE (t);
3208 decl = gfc_get_fake_result_decl (sym: sym->ns->proc_name, parent_flag);
3209
3210 if (parent_flag)
3211 this_fake_result_decl = parent_fake_result_decl;
3212 else
3213 this_fake_result_decl = current_fake_result_decl;
3214
3215 if (decl && sym->ns->proc_name->attr.mixed_entry_master)
3216 {
3217 tree field;
3218
3219 for (field = TYPE_FIELDS (TREE_TYPE (decl));
3220 field; field = DECL_CHAIN (field))
3221 if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
3222 s2: sym->name) == 0)
3223 break;
3224
3225 gcc_assert (field != NULL_TREE);
3226 decl = fold_build3_loc (input_location, COMPONENT_REF,
3227 TREE_TYPE (field), decl, field, NULL_TREE);
3228 }
3229
3230 var = create_tmp_var_raw (TREE_TYPE (decl), sym->name);
3231 if (parent_flag)
3232 gfc_add_decl_to_parent_function (decl: var);
3233 else
3234 gfc_add_decl_to_function (decl: var);
3235
3236 SET_DECL_VALUE_EXPR (var, decl);
3237 DECL_HAS_VALUE_EXPR_P (var) = 1;
3238 GFC_DECL_RESULT (var) = 1;
3239
3240 TREE_CHAIN (this_fake_result_decl)
3241 = tree_cons (get_identifier (sym->name), var,
3242 TREE_CHAIN (this_fake_result_decl));
3243 return var;
3244 }
3245
3246 if (this_fake_result_decl != NULL_TREE)
3247 return TREE_VALUE (this_fake_result_decl);
3248
3249 /* Only when gfc_get_fake_result_decl is called by gfc_trans_return,
3250 sym is NULL. */
3251 if (!sym)
3252 return NULL_TREE;
3253
3254 if (sym->ts.type == BT_CHARACTER)
3255 {
3256 if (sym->ts.u.cl->backend_decl == NULL_TREE)
3257 length = gfc_create_string_length (sym);
3258 else
3259 length = sym->ts.u.cl->backend_decl;
3260 if (VAR_P (length) && DECL_CONTEXT (length) == NULL_TREE)
3261 gfc_add_decl_to_function (decl: length);
3262 }
3263
3264 if (gfc_return_by_reference (sym))
3265 {
3266 decl = DECL_ARGUMENTS (this_function_decl);
3267
3268 if (sym->ns->proc_name->backend_decl == this_function_decl
3269 && sym->ns->proc_name->attr.entry_master)
3270 decl = DECL_CHAIN (decl);
3271
3272 TREE_USED (decl) = 1;
3273 if (sym->as)
3274 decl = gfc_build_dummy_array_decl (sym, dummy: decl);
3275 }
3276 else
3277 {
3278 sprintf (s: name, format: "__result_%.20s",
3279 IDENTIFIER_POINTER (DECL_NAME (this_function_decl)));
3280
3281 if (!sym->attr.mixed_entry_master && sym->attr.function)
3282 decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
3283 VAR_DECL, get_identifier (name),
3284 gfc_sym_type (sym));
3285 else
3286 decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
3287 VAR_DECL, get_identifier (name),
3288 TREE_TYPE (TREE_TYPE (this_function_decl)));
3289 DECL_ARTIFICIAL (decl) = 1;
3290 DECL_EXTERNAL (decl) = 0;
3291 TREE_PUBLIC (decl) = 0;
3292 TREE_USED (decl) = 1;
3293 GFC_DECL_RESULT (decl) = 1;
3294 TREE_ADDRESSABLE (decl) = 1;
3295
3296 layout_decl (decl, 0);
3297 gfc_finish_decl_attrs (decl, attr: &sym->attr);
3298
3299 if (parent_flag)
3300 gfc_add_decl_to_parent_function (decl);
3301 else
3302 gfc_add_decl_to_function (decl);
3303 }
3304
3305 if (parent_flag)
3306 parent_fake_result_decl = build_tree_list (NULL, decl);
3307 else
3308 current_fake_result_decl = build_tree_list (NULL, decl);
3309
3310 if (sym->attr.assign)
3311 DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl);
3312
3313 return decl;
3314}
3315
3316
3317/* Builds a function decl. The remaining parameters are the types of the
3318 function arguments. Negative nargs indicates a varargs function. */
3319
3320static tree
3321build_library_function_decl_1 (tree name, const char *spec,
3322 tree rettype, int nargs, va_list p)
3323{
3324 vec<tree, va_gc> *arglist;
3325 tree fntype;
3326 tree fndecl;
3327 int n;
3328
3329 /* Library functions must be declared with global scope. */
3330 gcc_assert (current_function_decl == NULL_TREE);
3331
3332 /* Create a list of the argument types. */
3333 vec_alloc (v&: arglist, nelems: abs (x: nargs));
3334 for (n = abs (x: nargs); n > 0; n--)
3335 {
3336 tree argtype = va_arg (p, tree);
3337 arglist->quick_push (obj: argtype);
3338 }
3339
3340 /* Build the function type and decl. */
3341 if (nargs >= 0)
3342 fntype = build_function_type_vec (rettype, arglist);
3343 else
3344 fntype = build_varargs_function_type_vec (rettype, arglist);
3345 if (spec)
3346 {
3347 tree attr_args = build_tree_list (NULL_TREE,
3348 build_string (strlen (s: spec), spec));
3349 tree attrs = tree_cons (get_identifier ("fn spec"),
3350 attr_args, TYPE_ATTRIBUTES (fntype));
3351 fntype = build_type_attribute_variant (fntype, attrs);
3352 }
3353 fndecl = build_decl (input_location,
3354 FUNCTION_DECL, name, fntype);
3355
3356 /* Mark this decl as external. */
3357 DECL_EXTERNAL (fndecl) = 1;
3358 TREE_PUBLIC (fndecl) = 1;
3359
3360 pushdecl (fndecl);
3361
3362 rest_of_decl_compilation (fndecl, 1, 0);
3363
3364 return fndecl;
3365}
3366
3367/* Builds a function decl. The remaining parameters are the types of the
3368 function arguments. Negative nargs indicates a varargs function. */
3369
3370tree
3371gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
3372{
3373 tree ret;
3374 va_list args;
3375 va_start (args, nargs);
3376 ret = build_library_function_decl_1 (name, NULL, rettype, nargs, p: args);
3377 va_end (args);
3378 return ret;
3379}
3380
3381/* Builds a function decl. The remaining parameters are the types of the
3382 function arguments. Negative nargs indicates a varargs function.
3383 The SPEC parameter specifies the function argument and return type
3384 specification according to the fnspec function type attribute. */
3385
3386tree
3387gfc_build_library_function_decl_with_spec (tree name, const char *spec,
3388 tree rettype, int nargs, ...)
3389{
3390 tree ret;
3391 va_list args;
3392 va_start (args, nargs);
3393 if (flag_checking)
3394 {
3395 attr_fnspec fnspec (spec, strlen (s: spec));
3396 fnspec.verify ();
3397 }
3398 ret = build_library_function_decl_1 (name, spec, rettype, nargs, p: args);
3399 va_end (args);
3400 return ret;
3401}
3402
3403static void
3404gfc_build_intrinsic_function_decls (void)
3405{
3406 tree gfc_int4_type_node = gfc_get_int_type (4);
3407 tree gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
3408 tree gfc_int8_type_node = gfc_get_int_type (8);
3409 tree gfc_pint8_type_node = build_pointer_type (gfc_int8_type_node);
3410 tree gfc_int16_type_node = gfc_get_int_type (16);
3411 tree gfc_logical4_type_node = gfc_get_logical_type (4);
3412 tree pchar1_type_node = gfc_get_pchar_type (1);
3413 tree pchar4_type_node = gfc_get_pchar_type (4);
3414
3415 /* String functions. */
3416 gfor_fndecl_compare_string = gfc_build_library_function_decl_with_spec (
3417 get_identifier (PREFIX("compare_string")), spec: ". . R . R ",
3418 integer_type_node, nargs: 4, gfc_charlen_type_node, pchar1_type_node,
3419 gfc_charlen_type_node, pchar1_type_node);
3420 DECL_PURE_P (gfor_fndecl_compare_string) = 1;
3421 TREE_NOTHROW (gfor_fndecl_compare_string) = 1;
3422
3423 gfor_fndecl_concat_string = gfc_build_library_function_decl_with_spec (
3424 get_identifier (PREFIX("concat_string")), spec: ". . W . R . R ",
3425 void_type_node, nargs: 6, gfc_charlen_type_node, pchar1_type_node,
3426 gfc_charlen_type_node, pchar1_type_node,
3427 gfc_charlen_type_node, pchar1_type_node);
3428 TREE_NOTHROW (gfor_fndecl_concat_string) = 1;
3429
3430 gfor_fndecl_string_len_trim = gfc_build_library_function_decl_with_spec (
3431 get_identifier (PREFIX("string_len_trim")), spec: ". . R ",
3432 rettype: gfc_charlen_type_node, nargs: 2, gfc_charlen_type_node, pchar1_type_node);
3433 DECL_PURE_P (gfor_fndecl_string_len_trim) = 1;
3434 TREE_NOTHROW (gfor_fndecl_string_len_trim) = 1;
3435
3436 gfor_fndecl_string_index = gfc_build_library_function_decl_with_spec (
3437 get_identifier (PREFIX("string_index")), spec: ". . R . R . ",
3438 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar1_type_node,
3439 gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3440 DECL_PURE_P (gfor_fndecl_string_index) = 1;
3441 TREE_NOTHROW (gfor_fndecl_string_index) = 1;
3442
3443 gfor_fndecl_string_scan = gfc_build_library_function_decl_with_spec (
3444 get_identifier (PREFIX("string_scan")), spec: ". . R . R . ",
3445 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar1_type_node,
3446 gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3447 DECL_PURE_P (gfor_fndecl_string_scan) = 1;
3448 TREE_NOTHROW (gfor_fndecl_string_scan) = 1;
3449
3450 gfor_fndecl_string_verify = gfc_build_library_function_decl_with_spec (
3451 get_identifier (PREFIX("string_verify")), spec: ". . R . R . ",
3452 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar1_type_node,
3453 gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3454 DECL_PURE_P (gfor_fndecl_string_verify) = 1;
3455 TREE_NOTHROW (gfor_fndecl_string_verify) = 1;
3456
3457 gfor_fndecl_string_trim = gfc_build_library_function_decl_with_spec (
3458 get_identifier (PREFIX("string_trim")), spec: ". W w . R ",
3459 void_type_node, nargs: 4, build_pointer_type (gfc_charlen_type_node),
3460 build_pointer_type (pchar1_type_node), gfc_charlen_type_node,
3461 pchar1_type_node);
3462
3463 gfor_fndecl_string_minmax = gfc_build_library_function_decl_with_spec (
3464 get_identifier (PREFIX("string_minmax")), spec: ". W w . R ",
3465 void_type_node, nargs: -4, build_pointer_type (gfc_charlen_type_node),
3466 build_pointer_type (pchar1_type_node), integer_type_node,
3467 integer_type_node);
3468
3469 gfor_fndecl_adjustl = gfc_build_library_function_decl_with_spec (
3470 get_identifier (PREFIX("adjustl")), spec: ". W . R ",
3471 void_type_node, nargs: 3, pchar1_type_node, gfc_charlen_type_node,
3472 pchar1_type_node);
3473 TREE_NOTHROW (gfor_fndecl_adjustl) = 1;
3474
3475 gfor_fndecl_adjustr = gfc_build_library_function_decl_with_spec (
3476 get_identifier (PREFIX("adjustr")), spec: ". W . R ",
3477 void_type_node, nargs: 3, pchar1_type_node, gfc_charlen_type_node,
3478 pchar1_type_node);
3479 TREE_NOTHROW (gfor_fndecl_adjustr) = 1;
3480
3481 gfor_fndecl_select_string = gfc_build_library_function_decl_with_spec (
3482 get_identifier (PREFIX("select_string")), spec: ". R . R . ",
3483 integer_type_node, nargs: 4, pvoid_type_node, integer_type_node,
3484 pchar1_type_node, gfc_charlen_type_node);
3485 DECL_PURE_P (gfor_fndecl_select_string) = 1;
3486 TREE_NOTHROW (gfor_fndecl_select_string) = 1;
3487
3488 gfor_fndecl_compare_string_char4 = gfc_build_library_function_decl_with_spec (
3489 get_identifier (PREFIX("compare_string_char4")), spec: ". . R . R ",
3490 integer_type_node, nargs: 4, gfc_charlen_type_node, pchar4_type_node,
3491 gfc_charlen_type_node, pchar4_type_node);
3492 DECL_PURE_P (gfor_fndecl_compare_string_char4) = 1;
3493 TREE_NOTHROW (gfor_fndecl_compare_string_char4) = 1;
3494
3495 gfor_fndecl_concat_string_char4 = gfc_build_library_function_decl_with_spec (
3496 get_identifier (PREFIX("concat_string_char4")), spec: ". . W . R . R ",
3497 void_type_node, nargs: 6, gfc_charlen_type_node, pchar4_type_node,
3498 gfc_charlen_type_node, pchar4_type_node, gfc_charlen_type_node,
3499 pchar4_type_node);
3500 TREE_NOTHROW (gfor_fndecl_concat_string_char4) = 1;
3501
3502 gfor_fndecl_string_len_trim_char4 = gfc_build_library_function_decl_with_spec (
3503 get_identifier (PREFIX("string_len_trim_char4")), spec: ". . R ",
3504 rettype: gfc_charlen_type_node, nargs: 2, gfc_charlen_type_node, pchar4_type_node);
3505 DECL_PURE_P (gfor_fndecl_string_len_trim_char4) = 1;
3506 TREE_NOTHROW (gfor_fndecl_string_len_trim_char4) = 1;
3507
3508 gfor_fndecl_string_index_char4 = gfc_build_library_function_decl_with_spec (
3509 get_identifier (PREFIX("string_index_char4")), spec: ". . R . R . ",
3510 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar4_type_node,
3511 gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3512 DECL_PURE_P (gfor_fndecl_string_index_char4) = 1;
3513 TREE_NOTHROW (gfor_fndecl_string_index_char4) = 1;
3514
3515 gfor_fndecl_string_scan_char4 = gfc_build_library_function_decl_with_spec (
3516 get_identifier (PREFIX("string_scan_char4")), spec: ". . R . R . ",
3517 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar4_type_node,
3518 gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3519 DECL_PURE_P (gfor_fndecl_string_scan_char4) = 1;
3520 TREE_NOTHROW (gfor_fndecl_string_scan_char4) = 1;
3521
3522 gfor_fndecl_string_verify_char4 = gfc_build_library_function_decl_with_spec (
3523 get_identifier (PREFIX("string_verify_char4")), spec: ". . R . R . ",
3524 rettype: gfc_charlen_type_node, nargs: 5, gfc_charlen_type_node, pchar4_type_node,
3525 gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3526 DECL_PURE_P (gfor_fndecl_string_verify_char4) = 1;
3527 TREE_NOTHROW (gfor_fndecl_string_verify_char4) = 1;
3528
3529 gfor_fndecl_string_trim_char4 = gfc_build_library_function_decl_with_spec (
3530 get_identifier (PREFIX("string_trim_char4")), spec: ". W w . R ",
3531 void_type_node, nargs: 4, build_pointer_type (gfc_charlen_type_node),
3532 build_pointer_type (pchar4_type_node), gfc_charlen_type_node,
3533 pchar4_type_node);
3534
3535 gfor_fndecl_string_minmax_char4 = gfc_build_library_function_decl_with_spec (
3536 get_identifier (PREFIX("string_minmax_char4")), spec: ". W w . R ",
3537 void_type_node, nargs: -4, build_pointer_type (gfc_charlen_type_node),
3538 build_pointer_type (pchar4_type_node), integer_type_node,
3539 integer_type_node);
3540
3541 gfor_fndecl_adjustl_char4 = gfc_build_library_function_decl_with_spec (
3542 get_identifier (PREFIX("adjustl_char4")), spec: ". W . R ",
3543 void_type_node, nargs: 3, pchar4_type_node, gfc_charlen_type_node,
3544 pchar4_type_node);
3545 TREE_NOTHROW (gfor_fndecl_adjustl_char4) = 1;
3546
3547 gfor_fndecl_adjustr_char4 = gfc_build_library_function_decl_with_spec (
3548 get_identifier (PREFIX("adjustr_char4")), spec: ". W . R ",
3549 void_type_node, nargs: 3, pchar4_type_node, gfc_charlen_type_node,
3550 pchar4_type_node);
3551 TREE_NOTHROW (gfor_fndecl_adjustr_char4) = 1;
3552
3553 gfor_fndecl_select_string_char4 = gfc_build_library_function_decl_with_spec (
3554 get_identifier (PREFIX("select_string_char4")), spec: ". R . R . ",
3555 integer_type_node, nargs: 4, pvoid_type_node, integer_type_node,
3556 pvoid_type_node, gfc_charlen_type_node);
3557 DECL_PURE_P (gfor_fndecl_select_string_char4) = 1;
3558 TREE_NOTHROW (gfor_fndecl_select_string_char4) = 1;
3559
3560
3561 /* Conversion between character kinds. */
3562
3563 gfor_fndecl_convert_char1_to_char4 = gfc_build_library_function_decl_with_spec (
3564 get_identifier (PREFIX("convert_char1_to_char4")), spec: ". w . R ",
3565 void_type_node, nargs: 3, build_pointer_type (pchar4_type_node),
3566 gfc_charlen_type_node, pchar1_type_node);
3567
3568 gfor_fndecl_convert_char4_to_char1 = gfc_build_library_function_decl_with_spec (
3569 get_identifier (PREFIX("convert_char4_to_char1")), spec: ". w . R ",
3570 void_type_node, nargs: 3, build_pointer_type (pchar1_type_node),
3571 gfc_charlen_type_node, pchar4_type_node);
3572
3573 /* Misc. functions. */
3574
3575 gfor_fndecl_ttynam = gfc_build_library_function_decl_with_spec (
3576 get_identifier (PREFIX("ttynam")), spec: ". W . . ",
3577 void_type_node, nargs: 3, pchar_type_node, gfc_charlen_type_node,
3578 integer_type_node);
3579
3580 gfor_fndecl_fdate = gfc_build_library_function_decl_with_spec (
3581 get_identifier (PREFIX("fdate")), spec: ". W . ",
3582 void_type_node, nargs: 2, pchar_type_node, gfc_charlen_type_node);
3583
3584 gfor_fndecl_ctime = gfc_build_library_function_decl_with_spec (
3585 get_identifier (PREFIX("ctime")), spec: ". W . . ",
3586 void_type_node, nargs: 3, pchar_type_node, gfc_charlen_type_node,
3587 gfc_int8_type_node);
3588
3589 gfor_fndecl_random_init = gfc_build_library_function_decl (
3590 get_identifier (PREFIX("random_init")),
3591 void_type_node, nargs: 3, gfc_logical4_type_node, gfc_logical4_type_node,
3592 gfc_int4_type_node);
3593
3594 // gfor_fndecl_caf_rand_init is defined in the lib-coarray section below.
3595
3596 gfor_fndecl_sc_kind = gfc_build_library_function_decl_with_spec (
3597 get_identifier (PREFIX("selected_char_kind")), spec: ". . R ",
3598 rettype: gfc_int4_type_node, nargs: 2, gfc_charlen_type_node, pchar_type_node);
3599 DECL_PURE_P (gfor_fndecl_sc_kind) = 1;
3600 TREE_NOTHROW (gfor_fndecl_sc_kind) = 1;
3601
3602 gfor_fndecl_si_kind = gfc_build_library_function_decl_with_spec (
3603 get_identifier (PREFIX("selected_int_kind")), spec: ". R ",
3604 rettype: gfc_int4_type_node, nargs: 1, pvoid_type_node);
3605 DECL_PURE_P (gfor_fndecl_si_kind) = 1;
3606 TREE_NOTHROW (gfor_fndecl_si_kind) = 1;
3607
3608 gfor_fndecl_sr_kind = gfc_build_library_function_decl_with_spec (
3609 get_identifier (PREFIX("selected_real_kind2008")), spec: ". R R ",
3610 rettype: gfc_int4_type_node, nargs: 3, pvoid_type_node, pvoid_type_node,
3611 pvoid_type_node);
3612 DECL_PURE_P (gfor_fndecl_sr_kind) = 1;
3613 TREE_NOTHROW (gfor_fndecl_sr_kind) = 1;
3614
3615 gfor_fndecl_system_clock4 = gfc_build_library_function_decl (
3616 get_identifier (PREFIX("system_clock_4")),
3617 void_type_node, nargs: 3, gfc_pint4_type_node, gfc_pint4_type_node,
3618 gfc_pint4_type_node);
3619
3620 gfor_fndecl_system_clock8 = gfc_build_library_function_decl (
3621 get_identifier (PREFIX("system_clock_8")),
3622 void_type_node, nargs: 3, gfc_pint8_type_node, gfc_pint8_type_node,
3623 gfc_pint8_type_node);
3624
3625 /* Power functions. */
3626 {
3627 tree ctype, rtype, itype, jtype;
3628 int rkind, ikind, jkind;
3629#define NIKINDS 3
3630#define NRKINDS 4
3631 static int ikinds[NIKINDS] = {4, 8, 16};
3632 static int rkinds[NRKINDS] = {4, 8, 10, 16};
3633 char name[PREFIX_LEN + 12]; /* _gfortran_pow_?n_?n */
3634
3635 for (ikind=0; ikind < NIKINDS; ikind++)
3636 {
3637 itype = gfc_get_int_type (ikinds[ikind]);
3638
3639 for (jkind=0; jkind < NIKINDS; jkind++)
3640 {
3641 jtype = gfc_get_int_type (ikinds[jkind]);
3642 if (itype && jtype)
3643 {
3644 sprintf (s: name, PREFIX("pow_i%d_i%d"), ikinds[ikind],
3645 ikinds[jkind]);
3646 gfor_fndecl_math_powi[jkind][ikind].integer =
3647 gfc_build_library_function_decl (get_identifier (name),
3648 rettype: jtype, nargs: 2, jtype, itype);
3649 TREE_READONLY (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
3650 TREE_NOTHROW (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
3651 }
3652 }
3653
3654 for (rkind = 0; rkind < NRKINDS; rkind ++)
3655 {
3656 rtype = gfc_get_real_type (rkinds[rkind]);
3657 if (rtype && itype)
3658 {
3659 sprintf (s: name, PREFIX("pow_r%d_i%d"),
3660 gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
3661 ikinds[ikind]);
3662 gfor_fndecl_math_powi[rkind][ikind].real =
3663 gfc_build_library_function_decl (get_identifier (name),
3664 rettype: rtype, nargs: 2, rtype, itype);
3665 TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
3666 TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
3667 }
3668
3669 ctype = gfc_get_complex_type (rkinds[rkind]);
3670 if (ctype && itype)
3671 {
3672 sprintf (s: name, PREFIX("pow_c%d_i%d"),
3673 gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
3674 ikinds[ikind]);
3675 gfor_fndecl_math_powi[rkind][ikind].cmplx =
3676 gfc_build_library_function_decl (get_identifier (name),
3677 rettype: ctype, nargs: 2,ctype, itype);
3678 TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
3679 TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
3680 }
3681 }
3682 }
3683#undef NIKINDS
3684#undef NRKINDS
3685 }
3686
3687 gfor_fndecl_math_ishftc4 = gfc_build_library_function_decl (
3688 get_identifier (PREFIX("ishftc4")),
3689 rettype: gfc_int4_type_node, nargs: 3, gfc_int4_type_node, gfc_int4_type_node,
3690 gfc_int4_type_node);
3691 TREE_READONLY (gfor_fndecl_math_ishftc4) = 1;
3692 TREE_NOTHROW (gfor_fndecl_math_ishftc4) = 1;
3693
3694 gfor_fndecl_math_ishftc8 = gfc_build_library_function_decl (
3695 get_identifier (PREFIX("ishftc8")),
3696 rettype: gfc_int8_type_node, nargs: 3, gfc_int8_type_node, gfc_int4_type_node,
3697 gfc_int4_type_node);
3698 TREE_READONLY (gfor_fndecl_math_ishftc8) = 1;
3699 TREE_NOTHROW (gfor_fndecl_math_ishftc8) = 1;
3700
3701 if (gfc_int16_type_node)
3702 {
3703 gfor_fndecl_math_ishftc16 = gfc_build_library_function_decl (
3704 get_identifier (PREFIX("ishftc16")),
3705 rettype: gfc_int16_type_node, nargs: 3, gfc_int16_type_node, gfc_int4_type_node,
3706 gfc_int4_type_node);
3707 TREE_READONLY (gfor_fndecl_math_ishftc16) = 1;
3708 TREE_NOTHROW (gfor_fndecl_math_ishftc16) = 1;
3709 }
3710
3711 /* BLAS functions. */
3712 {
3713 tree pint = build_pointer_type (integer_type_node);
3714 tree ps = build_pointer_type (gfc_get_real_type (gfc_default_real_kind));
3715 tree pd = build_pointer_type (gfc_get_real_type (gfc_default_double_kind));
3716 tree pc = build_pointer_type (gfc_get_complex_type (gfc_default_real_kind));
3717 tree pz = build_pointer_type
3718 (gfc_get_complex_type (gfc_default_double_kind));
3719
3720 gfor_fndecl_sgemm = gfc_build_library_function_decl
3721 (get_identifier
3722 (flag_underscoring ? "sgemm_" : "sgemm"),
3723 void_type_node, nargs: 15, pchar_type_node,
3724 pchar_type_node, pint, pint, pint, ps, ps, pint,
3725 ps, pint, ps, ps, pint, integer_type_node,
3726 integer_type_node);
3727 gfor_fndecl_dgemm = gfc_build_library_function_decl
3728 (get_identifier
3729 (flag_underscoring ? "dgemm_" : "dgemm"),
3730 void_type_node, nargs: 15, pchar_type_node,
3731 pchar_type_node, pint, pint, pint, pd, pd, pint,
3732 pd, pint, pd, pd, pint, integer_type_node,
3733 integer_type_node);
3734 gfor_fndecl_cgemm = gfc_build_library_function_decl
3735 (get_identifier
3736 (flag_underscoring ? "cgemm_" : "cgemm"),
3737 void_type_node, nargs: 15, pchar_type_node,
3738 pchar_type_node, pint, pint, pint, pc, pc, pint,
3739 pc, pint, pc, pc, pint, integer_type_node,
3740 integer_type_node);
3741 gfor_fndecl_zgemm = gfc_build_library_function_decl
3742 (get_identifier
3743 (flag_underscoring ? "zgemm_" : "zgemm"),
3744 void_type_node, nargs: 15, pchar_type_node,
3745 pchar_type_node, pint, pint, pint, pz, pz, pint,
3746 pz, pint, pz, pz, pint, integer_type_node,
3747 integer_type_node);
3748 }
3749
3750 /* Other functions. */
3751 gfor_fndecl_iargc = gfc_build_library_function_decl (
3752 get_identifier (PREFIX ("iargc")), rettype: gfc_int4_type_node, nargs: 0);
3753 TREE_NOTHROW (gfor_fndecl_iargc) = 1;
3754
3755 gfor_fndecl_kill_sub = gfc_build_library_function_decl (
3756 get_identifier (PREFIX ("kill_sub")), void_type_node,
3757 nargs: 3, gfc_int4_type_node, gfc_int4_type_node, gfc_pint4_type_node);
3758
3759 gfor_fndecl_kill = gfc_build_library_function_decl (
3760 get_identifier (PREFIX ("kill")), rettype: gfc_int4_type_node,
3761 nargs: 2, gfc_int4_type_node, gfc_int4_type_node);
3762
3763 gfor_fndecl_is_contiguous0 = gfc_build_library_function_decl_with_spec (
3764 get_identifier (PREFIX("is_contiguous0")), spec: ". R ",
3765 rettype: gfc_int4_type_node, nargs: 1, pvoid_type_node);
3766 DECL_PURE_P (gfor_fndecl_is_contiguous0) = 1;
3767 TREE_NOTHROW (gfor_fndecl_is_contiguous0) = 1;
3768}
3769
3770
3771/* Make prototypes for runtime library functions. */
3772
3773void
3774gfc_build_builtin_function_decls (void)
3775{
3776 tree gfc_int8_type_node = gfc_get_int_type (8);
3777
3778 gfor_fndecl_stop_numeric = gfc_build_library_function_decl (
3779 get_identifier (PREFIX("stop_numeric")),
3780 void_type_node, nargs: 2, integer_type_node, boolean_type_node);
3781 /* STOP doesn't return. */
3782 TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric) = 1;
3783
3784 gfor_fndecl_stop_string = gfc_build_library_function_decl_with_spec (
3785 get_identifier (PREFIX("stop_string")), spec: ". R . . ",
3786 void_type_node, nargs: 3, pchar_type_node, size_type_node,
3787 boolean_type_node);
3788 /* STOP doesn't return. */
3789 TREE_THIS_VOLATILE (gfor_fndecl_stop_string) = 1;
3790
3791 gfor_fndecl_error_stop_numeric = gfc_build_library_function_decl (
3792 get_identifier (PREFIX("error_stop_numeric")),
3793 void_type_node, nargs: 2, integer_type_node, boolean_type_node);
3794 /* ERROR STOP doesn't return. */
3795 TREE_THIS_VOLATILE (gfor_fndecl_error_stop_numeric) = 1;
3796
3797 gfor_fndecl_error_stop_string = gfc_build_library_function_decl_with_spec (
3798 get_identifier (PREFIX("error_stop_string")), spec: ". R . . ",
3799 void_type_node, nargs: 3, pchar_type_node, size_type_node,
3800 boolean_type_node);
3801 /* ERROR STOP doesn't return. */
3802 TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1;
3803
3804 gfor_fndecl_pause_numeric = gfc_build_library_function_decl (
3805 get_identifier (PREFIX("pause_numeric")),
3806 void_type_node, nargs: 1, gfc_int8_type_node);
3807
3808 gfor_fndecl_pause_string = gfc_build_library_function_decl_with_spec (
3809 get_identifier (PREFIX("pause_string")), spec: ". R . ",
3810 void_type_node, nargs: 2, pchar_type_node, size_type_node);
3811
3812 gfor_fndecl_runtime_error = gfc_build_library_function_decl_with_spec (
3813 get_identifier (PREFIX("runtime_error")), spec: ". R ",
3814 void_type_node, nargs: -1, pchar_type_node);
3815 /* The runtime_error function does not return. */
3816 TREE_THIS_VOLATILE (gfor_fndecl_runtime_error) = 1;
3817
3818 gfor_fndecl_runtime_error_at = gfc_build_library_function_decl_with_spec (
3819 get_identifier (PREFIX("runtime_error_at")), spec: ". R R ",
3820 void_type_node, nargs: -2, pchar_type_node, pchar_type_node);
3821 /* The runtime_error_at function does not return. */
3822 TREE_THIS_VOLATILE (gfor_fndecl_runtime_error_at) = 1;
3823
3824 gfor_fndecl_runtime_warning_at = gfc_build_library_function_decl_with_spec (
3825 get_identifier (PREFIX("runtime_warning_at")), spec: ". R R ",
3826 void_type_node, nargs: -2, pchar_type_node, pchar_type_node);
3827
3828 gfor_fndecl_generate_error = gfc_build_library_function_decl_with_spec (
3829 get_identifier (PREFIX("generate_error")), spec: ". W . R ",
3830 void_type_node, nargs: 3, pvoid_type_node, integer_type_node,
3831 pchar_type_node);
3832
3833 gfor_fndecl_os_error_at = gfc_build_library_function_decl_with_spec (
3834 get_identifier (PREFIX("os_error_at")), spec: ". R R ",
3835 void_type_node, nargs: -2, pchar_type_node, pchar_type_node);
3836 /* The os_error_at function does not return. */
3837 TREE_THIS_VOLATILE (gfor_fndecl_os_error_at) = 1;
3838
3839 gfor_fndecl_set_args = gfc_build_library_function_decl (
3840 get_identifier (PREFIX("set_args")),
3841 void_type_node, nargs: 2, integer_type_node,
3842 build_pointer_type (pchar_type_node));
3843
3844 gfor_fndecl_set_fpe = gfc_build_library_function_decl (
3845 get_identifier (PREFIX("set_fpe")),
3846 void_type_node, nargs: 1, integer_type_node);
3847
3848 gfor_fndecl_ieee_procedure_entry = gfc_build_library_function_decl (
3849 get_identifier (PREFIX("ieee_procedure_entry")),
3850 void_type_node, nargs: 1, pvoid_type_node);
3851
3852 gfor_fndecl_ieee_procedure_exit = gfc_build_library_function_decl (
3853 get_identifier (PREFIX("ieee_procedure_exit")),
3854 void_type_node, nargs: 1, pvoid_type_node);
3855
3856 /* Keep the array dimension in sync with the call, later in this file. */
3857 gfor_fndecl_set_options = gfc_build_library_function_decl_with_spec (
3858 get_identifier (PREFIX("set_options")), spec: ". . R ",
3859 void_type_node, nargs: 2, integer_type_node,
3860 build_pointer_type (integer_type_node));
3861
3862 gfor_fndecl_set_convert = gfc_build_library_function_decl (
3863 get_identifier (PREFIX("set_convert")),
3864 void_type_node, nargs: 1, integer_type_node);
3865
3866 gfor_fndecl_set_record_marker = gfc_build_library_function_decl (
3867 get_identifier (PREFIX("set_record_marker")),
3868 void_type_node, nargs: 1, integer_type_node);
3869
3870 gfor_fndecl_set_max_subrecord_length = gfc_build_library_function_decl (
3871 get_identifier (PREFIX("set_max_subrecord_length")),
3872 void_type_node, nargs: 1, integer_type_node);
3873
3874 gfor_fndecl_in_pack = gfc_build_library_function_decl_with_spec (
3875 get_identifier (PREFIX("internal_pack")), spec: ". r ",
3876 rettype: pvoid_type_node, nargs: 1, pvoid_type_node);
3877
3878 gfor_fndecl_in_unpack = gfc_build_library_function_decl_with_spec (
3879 get_identifier (PREFIX("internal_unpack")), spec: ". w R ",
3880 void_type_node, nargs: 2, pvoid_type_node, pvoid_type_node);
3881
3882 gfor_fndecl_associated = gfc_build_library_function_decl_with_spec (
3883 get_identifier (PREFIX("associated")), spec: ". R R ",
3884 integer_type_node, nargs: 2, ppvoid_type_node, ppvoid_type_node);
3885 DECL_PURE_P (gfor_fndecl_associated) = 1;
3886 TREE_NOTHROW (gfor_fndecl_associated) = 1;
3887
3888 /* Coarray library calls. */
3889 if (flag_coarray == GFC_FCOARRAY_LIB)
3890 {
3891 tree pint_type, pppchar_type;
3892
3893 pint_type = build_pointer_type (integer_type_node);
3894 pppchar_type
3895 = build_pointer_type (build_pointer_type (pchar_type_node));
3896
3897 gfor_fndecl_caf_init = gfc_build_library_function_decl_with_spec (
3898 get_identifier (PREFIX("caf_init")), spec: ". W W ",
3899 void_type_node, nargs: 2, pint_type, pppchar_type);
3900
3901 gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
3902 get_identifier (PREFIX("caf_finalize")), void_type_node, nargs: 0);
3903
3904 gfor_fndecl_caf_this_image = gfc_build_library_function_decl (
3905 get_identifier (PREFIX("caf_this_image")), integer_type_node,
3906 nargs: 1, integer_type_node);
3907
3908 gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
3909 get_identifier (PREFIX("caf_num_images")), integer_type_node,
3910 nargs: 2, integer_type_node, integer_type_node);
3911
3912 gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
3913 get_identifier (PREFIX("caf_register")), spec: ". . . W w w w . ",
3914 void_type_node, nargs: 7,
3915 size_type_node, integer_type_node, ppvoid_type_node, pvoid_type_node,
3916 pint_type, pchar_type_node, size_type_node);
3917
3918 gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec (
3919 get_identifier (PREFIX("caf_deregister")), spec: ". W . w w . ",
3920 void_type_node, nargs: 5,
3921 ppvoid_type_node, integer_type_node, pint_type, pchar_type_node,
3922 size_type_node);
3923
3924 gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
3925 get_identifier (PREFIX("caf_get")), spec: ". r . . r r w . . . w ",
3926 void_type_node, nargs: 10,
3927 pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
3928 pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
3929 boolean_type_node, pint_type);
3930
3931 gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
3932 get_identifier (PREFIX("caf_send")), spec: ". r . . w r r . . . w ",
3933 void_type_node, nargs: 11,
3934 pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
3935 pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
3936 boolean_type_node, pint_type, pvoid_type_node);
3937
3938 gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
3939 get_identifier (PREFIX("caf_sendget")), spec: ". r . . w r r . . r r . . . w ",
3940 void_type_node, nargs: 14, pvoid_type_node, size_type_node, integer_type_node,
3941 pvoid_type_node, pvoid_type_node, pvoid_type_node, size_type_node,
3942 integer_type_node, pvoid_type_node, pvoid_type_node, integer_type_node,
3943 integer_type_node, boolean_type_node, integer_type_node);
3944
3945 gfor_fndecl_caf_get_by_ref = gfc_build_library_function_decl_with_spec (
3946 get_identifier (PREFIX("caf_get_by_ref")), spec: ". r . w r . . . . w . ",
3947 void_type_node,
3948 nargs: 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3949 pvoid_type_node, integer_type_node, integer_type_node,
3950 boolean_type_node, boolean_type_node, pint_type, integer_type_node);
3951
3952 gfor_fndecl_caf_send_by_ref = gfc_build_library_function_decl_with_spec (
3953 get_identifier (PREFIX("caf_send_by_ref")), spec: ". r . r r . . . . w . ",
3954 void_type_node, nargs: 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3955 pvoid_type_node, integer_type_node, integer_type_node,
3956 boolean_type_node, boolean_type_node, pint_type, integer_type_node);
3957
3958 gfor_fndecl_caf_sendget_by_ref
3959 = gfc_build_library_function_decl_with_spec (
3960 get_identifier (PREFIX("caf_sendget_by_ref")),
3961 spec: ". r . r r . r . . . w w . . ",
3962 void_type_node, nargs: 13, pvoid_type_node, integer_type_node,
3963 pvoid_type_node, pvoid_type_node, integer_type_node,
3964 pvoid_type_node, integer_type_node, integer_type_node,
3965 boolean_type_node, pint_type, pint_type, integer_type_node,
3966 integer_type_node);
3967
3968 gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
3969 get_identifier (PREFIX("caf_sync_all")), spec: ". w w . ", void_type_node,
3970 nargs: 3, pint_type, pchar_type_node, size_type_node);
3971
3972 gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec (
3973 get_identifier (PREFIX("caf_sync_memory")), spec: ". w w . ", void_type_node,
3974 nargs: 3, pint_type, pchar_type_node, size_type_node);
3975
3976 gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec (
3977 get_identifier (PREFIX("caf_sync_images")), spec: ". . r w w . ", void_type_node,
3978 nargs: 5, integer_type_node, pint_type, pint_type,
3979 pchar_type_node, size_type_node);
3980
3981 gfor_fndecl_caf_error_stop = gfc_build_library_function_decl (
3982 get_identifier (PREFIX("caf_error_stop")),
3983 void_type_node, nargs: 1, integer_type_node);
3984 /* CAF's ERROR STOP doesn't return. */
3985 TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop) = 1;
3986
3987 gfor_fndecl_caf_error_stop_str = gfc_build_library_function_decl_with_spec (
3988 get_identifier (PREFIX("caf_error_stop_str")), spec: ". r . ",
3989 void_type_node, nargs: 2, pchar_type_node, size_type_node);
3990 /* CAF's ERROR STOP doesn't return. */
3991 TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1;
3992
3993 gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl (
3994 get_identifier (PREFIX("caf_stop_numeric")),
3995 void_type_node, nargs: 1, integer_type_node);
3996 /* CAF's STOP doesn't return. */
3997 TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1;
3998
3999 gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec (
4000 get_identifier (PREFIX("caf_stop_str")), spec: ". r . ",
4001 void_type_node, nargs: 2, pchar_type_node, size_type_node);
4002 /* CAF's STOP doesn't return. */
4003 TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
4004
4005 gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
4006 get_identifier (PREFIX("caf_atomic_define")), spec: ". r . . w w . . ",
4007 void_type_node, nargs: 7, pvoid_type_node, size_type_node, integer_type_node,
4008 pvoid_type_node, pint_type, integer_type_node, integer_type_node);
4009
4010 gfor_fndecl_caf_atomic_ref = gfc_build_library_function_decl_with_spec (
4011 get_identifier (PREFIX("caf_atomic_ref")), spec: ". r . . w w . . ",
4012 void_type_node, nargs: 7, pvoid_type_node, size_type_node, integer_type_node,
4013 pvoid_type_node, pint_type, integer_type_node, integer_type_node);
4014
4015 gfor_fndecl_caf_atomic_cas = gfc_build_library_function_decl_with_spec (
4016 get_identifier (PREFIX("caf_atomic_cas")), spec: ". r . . w r r w . . ",
4017 void_type_node, nargs: 9, pvoid_type_node, size_type_node, integer_type_node,
4018 pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
4019 integer_type_node, integer_type_node);
4020
4021 gfor_fndecl_caf_atomic_op = gfc_build_library_function_decl_with_spec (
4022 get_identifier (PREFIX("caf_atomic_op")), spec: ". . r . . r w w . . ",
4023 void_type_node, nargs: 9, integer_type_node, pvoid_type_node, size_type_node,
4024 integer_type_node, pvoid_type_node, pvoid_type_node, pint_type,
4025 integer_type_node, integer_type_node);
4026
4027 gfor_fndecl_caf_lock = gfc_build_library_function_decl_with_spec (
4028 get_identifier (PREFIX("caf_lock")), spec: ". r . . w w w . ",
4029 void_type_node, nargs: 7, pvoid_type_node, size_type_node, integer_type_node,
4030 pint_type, pint_type, pchar_type_node, size_type_node);
4031
4032 gfor_fndecl_caf_unlock = gfc_build_library_function_decl_with_spec (
4033 get_identifier (PREFIX("caf_unlock")), spec: ". r . . w w . ",
4034 void_type_node, nargs: 6, pvoid_type_node, size_type_node, integer_type_node,
4035 pint_type, pchar_type_node, size_type_node);
4036
4037 gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec (
4038 get_identifier (PREFIX("caf_event_post")), spec: ". r . . w w . ",
4039 void_type_node, nargs: 6, pvoid_type_node, size_type_node, integer_type_node,
4040 pint_type, pchar_type_node, size_type_node);
4041
4042 gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec (
4043 get_identifier (PREFIX("caf_event_wait")), spec: ". r . . w w . ",
4044 void_type_node, nargs: 6, pvoid_type_node, size_type_node, integer_type_node,
4045 pint_type, pchar_type_node, size_type_node);
4046
4047 gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec (
4048 get_identifier (PREFIX("caf_event_query")), spec: ". r . . w w ",
4049 void_type_node, nargs: 5, pvoid_type_node, size_type_node, integer_type_node,
4050 pint_type, pint_type);
4051
4052 gfor_fndecl_caf_fail_image = gfc_build_library_function_decl (
4053 get_identifier (PREFIX("caf_fail_image")), void_type_node, nargs: 0);
4054 /* CAF's FAIL doesn't return. */
4055 TREE_THIS_VOLATILE (gfor_fndecl_caf_fail_image) = 1;
4056
4057 gfor_fndecl_caf_failed_images
4058 = gfc_build_library_function_decl_with_spec (
4059 get_identifier (PREFIX("caf_failed_images")), spec: ". w . r ",
4060 void_type_node, nargs: 3, pvoid_type_node, ppvoid_type_node,
4061 integer_type_node);
4062
4063 gfor_fndecl_caf_form_team
4064 = gfc_build_library_function_decl_with_spec (
4065 get_identifier (PREFIX("caf_form_team")), spec: ". . W . ",
4066 void_type_node, nargs: 3, integer_type_node, ppvoid_type_node,
4067 integer_type_node);
4068
4069 gfor_fndecl_caf_change_team
4070 = gfc_build_library_function_decl_with_spec (
4071 get_identifier (PREFIX("caf_change_team")), spec: ". w . ",
4072 void_type_node, nargs: 2, ppvoid_type_node,
4073 integer_type_node);
4074
4075 gfor_fndecl_caf_end_team
4076 = gfc_build_library_function_decl (
4077 get_identifier (PREFIX("caf_end_team")), void_type_node, nargs: 0);
4078
4079 gfor_fndecl_caf_get_team
4080 = gfc_build_library_function_decl (
4081 get_identifier (PREFIX("caf_get_team")),
4082 void_type_node, nargs: 1, integer_type_node);
4083
4084 gfor_fndecl_caf_sync_team
4085 = gfc_build_library_function_decl_with_spec (
4086 get_identifier (PREFIX("caf_sync_team")), spec: ". r . ",
4087 void_type_node, nargs: 2, ppvoid_type_node,
4088 integer_type_node);
4089
4090 gfor_fndecl_caf_team_number
4091 = gfc_build_library_function_decl_with_spec (
4092 get_identifier (PREFIX("caf_team_number")), spec: ". r ",
4093 integer_type_node, nargs: 1, integer_type_node);
4094
4095 gfor_fndecl_caf_image_status
4096 = gfc_build_library_function_decl_with_spec (
4097 get_identifier (PREFIX("caf_image_status")), spec: ". . r ",
4098 integer_type_node, nargs: 2, integer_type_node, ppvoid_type_node);
4099
4100 gfor_fndecl_caf_stopped_images
4101 = gfc_build_library_function_decl_with_spec (
4102 get_identifier (PREFIX("caf_stopped_images")), spec: ". w r r ",
4103 void_type_node, nargs: 3, pvoid_type_node, ppvoid_type_node,
4104 integer_type_node);
4105
4106 gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec (
4107 get_identifier (PREFIX("caf_co_broadcast")), spec: ". w . w w . ",
4108 void_type_node, nargs: 5, pvoid_type_node, integer_type_node,
4109 pint_type, pchar_type_node, size_type_node);
4110
4111 gfor_fndecl_co_max = gfc_build_library_function_decl_with_spec (
4112 get_identifier (PREFIX("caf_co_max")), spec: ". w . w w . . ",
4113 void_type_node, nargs: 6, pvoid_type_node, integer_type_node,
4114 pint_type, pchar_type_node, integer_type_node, size_type_node);
4115
4116 gfor_fndecl_co_min = gfc_build_library_function_decl_with_spec (
4117 get_identifier (PREFIX("caf_co_min")), spec: ". w . w w . . ",
4118 void_type_node, nargs: 6, pvoid_type_node, integer_type_node,
4119 pint_type, pchar_type_node, integer_type_node, size_type_node);
4120
4121 gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec (
4122 get_identifier (PREFIX("caf_co_reduce")), spec: ". w r . . w w . . ",
4123 void_type_node, nargs: 8, pvoid_type_node,
4124 build_pointer_type (build_varargs_function_type_list (void_type_node,
4125 NULL_TREE)),
4126 integer_type_node, integer_type_node, pint_type, pchar_type_node,
4127 integer_type_node, size_type_node);
4128
4129 gfor_fndecl_co_sum = gfc_build_library_function_decl_with_spec (
4130 get_identifier (PREFIX("caf_co_sum")), spec: ". w . w w . ",
4131 void_type_node, nargs: 5, pvoid_type_node, integer_type_node,
4132 pint_type, pchar_type_node, size_type_node);
4133
4134 gfor_fndecl_caf_is_present = gfc_build_library_function_decl_with_spec (
4135 get_identifier (PREFIX("caf_is_present")), spec: ". r . r ",
4136 integer_type_node, nargs: 3, pvoid_type_node, integer_type_node,
4137 pvoid_type_node);
4138
4139 gfor_fndecl_caf_random_init = gfc_build_library_function_decl (
4140 get_identifier (PREFIX("caf_random_init")),
4141 void_type_node, nargs: 2, logical_type_node, logical_type_node);
4142 }
4143
4144 gfc_build_intrinsic_function_decls ();
4145 gfc_build_intrinsic_lib_fndecls ();
4146 gfc_build_io_library_fndecls ();
4147}
4148
4149
4150/* Evaluate the length of dummy character variables. */
4151
4152static void
4153gfc_trans_dummy_character (gfc_symbol *sym, gfc_charlen *cl,
4154 gfc_wrapped_block *block)
4155{
4156 stmtblock_t init;
4157
4158 gfc_finish_decl (decl: cl->backend_decl);
4159
4160 gfc_start_block (&init);
4161
4162 /* Evaluate the string length expression. */
4163 gfc_conv_string_length (cl, NULL, &init);
4164
4165 gfc_trans_vla_type_sizes (sym, &init);
4166
4167 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), NULL_TREE);
4168}
4169
4170
4171/* Allocate and cleanup an automatic character variable. */
4172
4173static void
4174gfc_trans_auto_character_variable (gfc_symbol * sym, gfc_wrapped_block * block)
4175{
4176 stmtblock_t init;
4177 tree decl;
4178 tree tmp;
4179
4180 gcc_assert (sym->backend_decl);
4181 gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length);
4182
4183 gfc_init_block (&init);
4184
4185 /* Evaluate the string length expression. */
4186 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4187
4188 gfc_trans_vla_type_sizes (sym, &init);
4189
4190 decl = sym->backend_decl;
4191
4192 /* Emit a DECL_EXPR for this variable, which will cause the
4193 gimplifier to allocate storage, and all that good stuff. */
4194 tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
4195 gfc_add_expr_to_block (&init, tmp);
4196
4197 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), NULL_TREE);
4198}
4199
4200/* Set the initial value of ASSIGN statement auxiliary variable explicitly. */
4201
4202static void
4203gfc_trans_assign_aux_var (gfc_symbol * sym, gfc_wrapped_block * block)
4204{
4205 stmtblock_t init;
4206
4207 gcc_assert (sym->backend_decl);
4208 gfc_start_block (&init);
4209
4210 /* Set the initial value to length. See the comments in
4211 function gfc_add_assign_aux_vars in this file. */
4212 gfc_add_modify (&init, GFC_DECL_STRING_LEN (sym->backend_decl),
4213 build_int_cst (gfc_charlen_type_node, -2));
4214
4215 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), NULL_TREE);
4216}
4217
4218static void
4219gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
4220{
4221 tree t = *tp, var, val;
4222
4223 if (t == NULL || t == error_mark_node)
4224 return;
4225 if (TREE_CONSTANT (t) || DECL_P (t))
4226 return;
4227
4228 if (TREE_CODE (t) == SAVE_EXPR)
4229 {
4230 if (SAVE_EXPR_RESOLVED_P (t))
4231 {
4232 *tp = TREE_OPERAND (t, 0);
4233 return;
4234 }
4235 val = TREE_OPERAND (t, 0);
4236 }
4237 else
4238 val = t;
4239
4240 var = gfc_create_var_np (TREE_TYPE (t), NULL);
4241 gfc_add_decl_to_function (decl: var);
4242 gfc_add_modify (body, var, unshare_expr (val));
4243 if (TREE_CODE (t) == SAVE_EXPR)
4244 TREE_OPERAND (t, 0) = var;
4245 *tp = var;
4246}
4247
4248static void
4249gfc_trans_vla_type_sizes_1 (tree type, stmtblock_t *body)
4250{
4251 tree t;
4252
4253 if (type == NULL || type == error_mark_node)
4254 return;
4255
4256 type = TYPE_MAIN_VARIANT (type);
4257
4258 if (TREE_CODE (type) == INTEGER_TYPE)
4259 {
4260 gfc_trans_vla_one_sizepos (tp: &TYPE_MIN_VALUE (type), body);
4261 gfc_trans_vla_one_sizepos (tp: &TYPE_MAX_VALUE (type), body);
4262
4263 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
4264 {
4265 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
4266 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
4267 }
4268 }
4269 else if (TREE_CODE (type) == ARRAY_TYPE)
4270 {
4271 gfc_trans_vla_type_sizes_1 (TREE_TYPE (type), body);
4272 gfc_trans_vla_type_sizes_1 (TYPE_DOMAIN (type), body);
4273 gfc_trans_vla_one_sizepos (tp: &TYPE_SIZE (type), body);
4274 gfc_trans_vla_one_sizepos (tp: &TYPE_SIZE_UNIT (type), body);
4275
4276 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
4277 {
4278 TYPE_SIZE (t) = TYPE_SIZE (type);
4279 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
4280 }
4281 }
4282}
4283
4284/* Make sure all type sizes and array domains are either constant,
4285 or variable or parameter decls. This is a simplified variant
4286 of gimplify_type_sizes, but we can't use it here, as none of the
4287 variables in the expressions have been gimplified yet.
4288 As type sizes and domains for various variable length arrays
4289 contain VAR_DECLs that are only initialized at gfc_trans_deferred_vars
4290 time, without this routine gimplify_type_sizes in the middle-end
4291 could result in the type sizes being gimplified earlier than where
4292 those variables are initialized. */
4293
4294void
4295gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
4296{
4297 tree type = TREE_TYPE (sym->backend_decl);
4298
4299 if (TREE_CODE (type) == FUNCTION_TYPE
4300 && (sym->attr.function || sym->attr.result || sym->attr.entry))
4301 {
4302 if (! current_fake_result_decl)
4303 return;
4304
4305 type = TREE_TYPE (TREE_VALUE (current_fake_result_decl));
4306 }
4307
4308 while (POINTER_TYPE_P (type))
4309 type = TREE_TYPE (type);
4310
4311 if (GFC_DESCRIPTOR_TYPE_P (type))
4312 {
4313 tree etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
4314
4315 while (POINTER_TYPE_P (etype))
4316 etype = TREE_TYPE (etype);
4317
4318 gfc_trans_vla_type_sizes_1 (type: etype, body);
4319 }
4320
4321 gfc_trans_vla_type_sizes_1 (type, body);
4322}
4323
4324
4325/* Initialize a derived type by building an lvalue from the symbol
4326 and using trans_assignment to do the work. Set dealloc to false
4327 if no deallocation prior the assignment is needed. */
4328void
4329gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc)
4330{
4331 gfc_expr *e;
4332 tree tmp;
4333 tree present;
4334
4335 gcc_assert (block);
4336
4337 /* Initialization of PDTs is done elsewhere. */
4338 if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
4339 return;
4340
4341 gcc_assert (!sym->attr.allocatable);
4342 gfc_set_sym_referenced (sym);
4343 e = gfc_lval_expr_from_sym (sym);
4344 tmp = gfc_trans_assignment (e, sym->value, false, dealloc);
4345 if (sym->attr.dummy && (sym->attr.optional
4346 || sym->ns->proc_name->attr.entry_master))
4347 {
4348 present = gfc_conv_expr_present (sym);
4349 tmp = build3_loc (loc: input_location, code: COND_EXPR, TREE_TYPE (tmp), arg0: present,
4350 arg1: tmp, arg2: build_empty_stmt (input_location));
4351 }
4352 gfc_add_expr_to_block (block, tmp);
4353 gfc_free_expr (e);
4354}
4355
4356
4357/* Initialize INTENT(OUT) derived type dummies. As well as giving
4358 them their default initializer, if they have allocatable
4359 components, they have their allocatable components deallocated. */
4360
4361static void
4362init_intent_out_dt (gfc_symbol * proc_sym, gfc_wrapped_block * block)
4363{
4364 stmtblock_t init;
4365 gfc_formal_arglist *f;
4366 tree tmp;
4367 tree present;
4368 gfc_symbol *s;
4369 bool dealloc_with_value = false;
4370
4371 gfc_init_block (&init);
4372 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
4373 if (f->sym && f->sym->attr.intent == INTENT_OUT
4374 && !f->sym->attr.pointer
4375 && f->sym->ts.type == BT_DERIVED)
4376 {
4377 s = f->sym;
4378 tmp = NULL_TREE;
4379
4380 /* Note: Allocatables are excluded as they are already handled
4381 by the caller. */
4382 if (!f->sym->attr.allocatable
4383 && gfc_is_finalizable (s->ts.u.derived, NULL))
4384 {
4385 stmtblock_t block;
4386 gfc_expr *e;
4387
4388 gfc_init_block (&block);
4389 s->attr.referenced = 1;
4390 e = gfc_lval_expr_from_sym (s);
4391 gfc_add_finalizer_call (&block, e);
4392 gfc_free_expr (e);
4393 tmp = gfc_finish_block (&block);
4394 }
4395
4396 /* Note: Allocatables are excluded as they are already handled
4397 by the caller. */
4398 if (tmp == NULL_TREE && !s->attr.allocatable
4399 && s->ts.u.derived->attr.alloc_comp)
4400 {
4401 tmp = gfc_deallocate_alloc_comp (s->ts.u.derived,
4402 s->backend_decl,
4403 s->as ? s->as->rank : 0);
4404 dealloc_with_value = s->value;
4405 }
4406
4407 if (tmp != NULL_TREE && (s->attr.optional
4408 || s->ns->proc_name->attr.entry_master))
4409 {
4410 present = gfc_conv_expr_present (s);
4411 tmp = build3_loc (loc: input_location, code: COND_EXPR, TREE_TYPE (tmp),
4412 arg0: present, arg1: tmp, arg2: build_empty_stmt (input_location));
4413 }
4414
4415 if (tmp != NULL_TREE && !dealloc_with_value)
4416 gfc_add_expr_to_block (&init, tmp);
4417 else if (s->value && !s->attr.allocatable)
4418 {
4419 gfc_add_expr_to_block (&init, tmp);
4420 gfc_init_default_dt (sym: s, block: &init, dealloc: false);
4421 dealloc_with_value = false;
4422 }
4423 }
4424 else if (f->sym && f->sym->attr.intent == INTENT_OUT
4425 && f->sym->ts.type == BT_CLASS
4426 && !CLASS_DATA (f->sym)->attr.class_pointer
4427 && !CLASS_DATA (f->sym)->attr.allocatable)
4428 {
4429 stmtblock_t block;
4430 gfc_expr *e;
4431
4432 gfc_init_block (&block);
4433 f->sym->attr.referenced = 1;
4434 e = gfc_lval_expr_from_sym (f->sym);
4435 gfc_add_finalizer_call (&block, e);
4436 gfc_free_expr (e);
4437 tmp = gfc_finish_block (&block);
4438
4439 if (f->sym->attr.optional || f->sym->ns->proc_name->attr.entry_master)
4440 {
4441 present = gfc_conv_expr_present (f->sym);
4442 tmp = build3_loc (loc: input_location, code: COND_EXPR, TREE_TYPE (tmp),
4443 arg0: present, arg1: tmp,
4444 arg2: build_empty_stmt (input_location));
4445 }
4446 gfc_add_expr_to_block (&init, tmp);
4447 }
4448 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), NULL_TREE);
4449}
4450
4451
4452/* Helper function to manage deferred string lengths. */
4453
4454static tree
4455gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
4456 locus *loc)
4457{
4458 tree tmp;
4459
4460 /* Character length passed by reference. */
4461 tmp = sym->ts.u.cl->passed_length;
4462 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4463 tmp = fold_convert (gfc_charlen_type_node, tmp);
4464
4465 if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
4466 /* Zero the string length when entering the scope. */
4467 gfc_add_modify (init, sym->ts.u.cl->backend_decl,
4468 build_int_cst (gfc_charlen_type_node, 0));
4469 else
4470 {
4471 tree tmp2;
4472
4473 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR,
4474 gfc_charlen_type_node,
4475 sym->ts.u.cl->backend_decl, tmp);
4476 if (sym->attr.optional)
4477 {
4478 tree present = gfc_conv_expr_present (sym);
4479 tmp2 = build3_loc (loc: input_location, code: COND_EXPR,
4480 void_type_node, arg0: present, arg1: tmp2,
4481 arg2: build_empty_stmt (input_location));
4482 }
4483 gfc_add_expr_to_block (init, tmp2);
4484 }
4485
4486 gfc_restore_backend_locus (loc);
4487
4488 /* Pass the final character length back. */
4489 if (sym->attr.intent != INTENT_IN)
4490 {
4491 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4492 gfc_charlen_type_node, tmp,
4493 sym->ts.u.cl->backend_decl);
4494 if (sym->attr.optional)
4495 {
4496 tree present = gfc_conv_expr_present (sym);
4497 tmp = build3_loc (loc: input_location, code: COND_EXPR,
4498 void_type_node, arg0: present, arg1: tmp,
4499 arg2: build_empty_stmt (input_location));
4500 }
4501 }
4502 else
4503 tmp = NULL_TREE;
4504
4505 return tmp;
4506}
4507
4508
4509/* Get the result expression for a procedure. */
4510
4511static tree
4512get_proc_result (gfc_symbol* sym)
4513{
4514 if (sym->attr.subroutine || sym == sym->result)
4515 {
4516 if (current_fake_result_decl != NULL)
4517 return TREE_VALUE (current_fake_result_decl);
4518
4519 return NULL_TREE;
4520 }
4521
4522 return sym->result->backend_decl;
4523}
4524
4525
4526/* Generate function entry and exit code, and add it to the function body.
4527 This includes:
4528 Allocation and initialization of array variables.
4529 Allocation of character string variables.
4530 Initialization and possibly repacking of dummy arrays.
4531 Initialization of ASSIGN statement auxiliary variable.
4532 Initialization of ASSOCIATE names.
4533 Automatic deallocation. */
4534
4535void
4536gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
4537{
4538 locus loc;
4539 gfc_symbol *sym;
4540 gfc_formal_arglist *f;
4541 stmtblock_t tmpblock;
4542 bool seen_trans_deferred_array = false;
4543 bool is_pdt_type = false;
4544 tree tmp = NULL;
4545 gfc_expr *e;
4546 gfc_se se;
4547 stmtblock_t init;
4548
4549 /* Deal with implicit return variables. Explicit return variables will
4550 already have been added. */
4551 if (gfc_return_by_reference (proc_sym) && proc_sym->result == proc_sym)
4552 {
4553 if (!current_fake_result_decl)
4554 {
4555 gfc_entry_list *el = NULL;
4556 if (proc_sym->attr.entry_master)
4557 {
4558 for (el = proc_sym->ns->entries; el; el = el->next)
4559 if (el->sym != el->sym->result)
4560 break;
4561 }
4562 /* TODO: move to the appropriate place in resolve.cc. */
4563 if (warn_return_type > 0 && el == NULL)
4564 gfc_warning (opt: OPT_Wreturn_type,
4565 "Return value of function %qs at %L not set",
4566 proc_sym->name, &proc_sym->declared_at);
4567 }
4568 else if (proc_sym->as)
4569 {
4570 tree result = TREE_VALUE (current_fake_result_decl);
4571 gfc_save_backend_locus (&loc);
4572 gfc_set_backend_locus (&proc_sym->declared_at);
4573 gfc_trans_dummy_array_bias (proc_sym, result, block);
4574
4575 /* An automatic character length, pointer array result. */
4576 if (proc_sym->ts.type == BT_CHARACTER
4577 && VAR_P (proc_sym->ts.u.cl->backend_decl))
4578 {
4579 tmp = NULL;
4580 if (proc_sym->ts.deferred)
4581 {
4582 gfc_start_block (&init);
4583 tmp = gfc_null_and_pass_deferred_len (sym: proc_sym, init: &init, loc: &loc);
4584 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), cleanup: tmp);
4585 }
4586 else
4587 gfc_trans_dummy_character (sym: proc_sym, cl: proc_sym->ts.u.cl, block);
4588 }
4589 }
4590 else if (proc_sym->ts.type == BT_CHARACTER)
4591 {
4592 if (proc_sym->ts.deferred)
4593 {
4594 tmp = NULL;
4595 gfc_save_backend_locus (&loc);
4596 gfc_set_backend_locus (&proc_sym->declared_at);
4597 gfc_start_block (&init);
4598 /* Zero the string length on entry. */
4599 gfc_add_modify (&init, proc_sym->ts.u.cl->backend_decl,
4600 build_int_cst (gfc_charlen_type_node, 0));
4601 /* Null the pointer. */
4602 e = gfc_lval_expr_from_sym (proc_sym);
4603 gfc_init_se (&se, NULL);
4604 se.want_pointer = 1;
4605 gfc_conv_expr (se: &se, expr: e);
4606 gfc_free_expr (e);
4607 tmp = se.expr;
4608 gfc_add_modify (&init, tmp,
4609 fold_convert (TREE_TYPE (se.expr),
4610 null_pointer_node));
4611 gfc_restore_backend_locus (&loc);
4612
4613 /* Pass back the string length on exit. */
4614 tmp = proc_sym->ts.u.cl->backend_decl;
4615 if (TREE_CODE (tmp) != INDIRECT_REF
4616 && proc_sym->ts.u.cl->passed_length)
4617 {
4618 tmp = proc_sym->ts.u.cl->passed_length;
4619 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4620 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4621 TREE_TYPE (tmp), tmp,
4622 fold_convert
4623 (TREE_TYPE (tmp),
4624 proc_sym->ts.u.cl->backend_decl));
4625 }
4626 else
4627 tmp = NULL_TREE;
4628
4629 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), cleanup: tmp);
4630 }
4631 else if (VAR_P (proc_sym->ts.u.cl->backend_decl))
4632 gfc_trans_dummy_character (sym: proc_sym, cl: proc_sym->ts.u.cl, block);
4633 }
4634 else
4635 gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX);
4636 }
4637 else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
4638 {
4639 /* Nullify explicit return class arrays on entry. */
4640 tree type;
4641 tmp = get_proc_result (sym: proc_sym);
4642 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
4643 {
4644 gfc_start_block (&init);
4645 tmp = gfc_class_data_get (tmp);
4646 type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
4647 gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
4648 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), NULL_TREE);
4649 }
4650 }
4651
4652
4653 /* Initialize the INTENT(OUT) derived type dummy arguments. This
4654 should be done here so that the offsets and lbounds of arrays
4655 are available. */
4656 gfc_save_backend_locus (&loc);
4657 gfc_set_backend_locus (&proc_sym->declared_at);
4658 init_intent_out_dt (proc_sym, block);
4659 gfc_restore_backend_locus (&loc);
4660
4661 /* For some reasons, internal procedures point to the parent's
4662 namespace. Top-level procedure and variables inside BLOCK are fine. */
4663 gfc_namespace *omp_ns = proc_sym->ns;
4664 if (proc_sym->ns->proc_name != proc_sym)
4665 for (omp_ns = proc_sym->ns->contained; omp_ns;
4666 omp_ns = omp_ns->sibling)
4667 if (omp_ns->proc_name == proc_sym)
4668 break;
4669
4670 /* Add 'omp allocate' attribute for gfc_trans_auto_array_allocation and
4671 unset attr.omp_allocate for 'omp allocate allocator(omp_default_mem_alloc),
4672 which has the normal codepath except for an invalid-use check in the ME.
4673 The main processing happens later in this function. */
4674 for (struct gfc_omp_namelist *n = omp_ns ? omp_ns->omp_allocate : NULL;
4675 n; n = n->next)
4676 if (!TREE_STATIC (n->sym->backend_decl))
4677 {
4678 /* Add empty entries - described and to be filled below. */
4679 tree tmp = build_tree_list (NULL_TREE, NULL_TREE);
4680 TREE_CHAIN (tmp) = build_tree_list (NULL_TREE, NULL_TREE);
4681 DECL_ATTRIBUTES (n->sym->backend_decl)
4682 = tree_cons (get_identifier ("omp allocate"), tmp,
4683 DECL_ATTRIBUTES (n->sym->backend_decl));
4684 if (n->u.align == NULL
4685 && n->u2.allocator != NULL
4686 && n->u2.allocator->expr_type == EXPR_CONSTANT
4687 && mpz_cmp_si (n->u2.allocator->value.integer, 1) == 0)
4688 n->sym->attr.omp_allocate = 0;
4689 }
4690
4691 for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
4692 {
4693 bool alloc_comp_or_fini = (sym->ts.type == BT_DERIVED)
4694 && (sym->ts.u.derived->attr.alloc_comp
4695 || gfc_is_finalizable (sym->ts.u.derived,
4696 NULL));
4697 if (sym->assoc)
4698 continue;
4699
4700 /* Set the vptr of unlimited polymorphic pointer variables so that
4701 they do not cause segfaults in select type, when the selector
4702 is an intrinsic type. */
4703 if (sym->ts.type == BT_CLASS && UNLIMITED_POLY (sym)
4704 && sym->attr.flavor == FL_VARIABLE && !sym->assoc
4705 && !sym->attr.dummy && CLASS_DATA (sym)->attr.class_pointer)
4706 {
4707 gfc_symbol *vtab;
4708 gfc_init_block (&tmpblock);
4709 vtab = gfc_find_vtab (&sym->ts);
4710 if (!vtab->backend_decl)
4711 {
4712 if (!vtab->attr.referenced)
4713 gfc_set_sym_referenced (vtab);
4714 gfc_get_symbol_decl (sym: vtab);
4715 }
4716 tmp = gfc_class_vptr_get (sym->backend_decl);
4717 gfc_add_modify (&tmpblock, tmp,
4718 gfc_build_addr_expr (TREE_TYPE (tmp),
4719 vtab->backend_decl));
4720 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), NULL);
4721 }
4722
4723 if (sym->ts.type == BT_DERIVED
4724 && sym->ts.u.derived
4725 && sym->ts.u.derived->attr.pdt_type)
4726 {
4727 is_pdt_type = true;
4728 gfc_init_block (&tmpblock);
4729 if (!(sym->attr.dummy
4730 || sym->attr.pointer
4731 || sym->attr.allocatable))
4732 {
4733 tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
4734 sym->backend_decl,
4735 sym->as ? sym->as->rank : 0,
4736 sym->param_list);
4737 gfc_add_expr_to_block (&tmpblock, tmp);
4738 if (!sym->attr.result)
4739 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived,
4740 sym->backend_decl,
4741 sym->as ? sym->as->rank : 0);
4742 else
4743 tmp = NULL_TREE;
4744 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), cleanup: tmp);
4745 }
4746 else if (sym->attr.dummy)
4747 {
4748 tmp = gfc_check_pdt_dummy (sym->ts.u.derived,
4749 sym->backend_decl,
4750 sym->as ? sym->as->rank : 0,
4751 sym->param_list);
4752 gfc_add_expr_to_block (&tmpblock, tmp);
4753 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), NULL);
4754 }
4755 }
4756 else if (sym->ts.type == BT_CLASS
4757 && CLASS_DATA (sym)->ts.u.derived
4758 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
4759 {
4760 gfc_component *data = CLASS_DATA (sym);
4761 is_pdt_type = true;
4762 gfc_init_block (&tmpblock);
4763 if (!(sym->attr.dummy
4764 || CLASS_DATA (sym)->attr.pointer
4765 || CLASS_DATA (sym)->attr.allocatable))
4766 {
4767 tmp = gfc_class_data_get (sym->backend_decl);
4768 tmp = gfc_allocate_pdt_comp (data->ts.u.derived, tmp,
4769 data->as ? data->as->rank : 0,
4770 sym->param_list);
4771 gfc_add_expr_to_block (&tmpblock, tmp);
4772 tmp = gfc_class_data_get (sym->backend_decl);
4773 if (!sym->attr.result)
4774 tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp,
4775 data->as ? data->as->rank : 0);
4776 else
4777 tmp = NULL_TREE;
4778 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), cleanup: tmp);
4779 }
4780 else if (sym->attr.dummy)
4781 {
4782 tmp = gfc_class_data_get (sym->backend_decl);
4783 tmp = gfc_check_pdt_dummy (data->ts.u.derived, tmp,
4784 data->as ? data->as->rank : 0,
4785 sym->param_list);
4786 gfc_add_expr_to_block (&tmpblock, tmp);
4787 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), NULL);
4788 }
4789 }
4790
4791 if (sym->attr.pointer && sym->attr.dimension
4792 && sym->attr.save == SAVE_NONE
4793 && !sym->attr.use_assoc
4794 && !sym->attr.host_assoc
4795 && !sym->attr.dummy
4796 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
4797 {
4798 gfc_init_block (&tmpblock);
4799 gfc_conv_descriptor_span_set (&tmpblock, sym->backend_decl,
4800 build_int_cst (gfc_array_index_type, 0));
4801 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock),
4802 NULL_TREE);
4803 }
4804
4805 if (sym->ts.type == BT_CLASS
4806 && (sym->attr.save || flag_max_stack_var_size == 0)
4807 && CLASS_DATA (sym)->attr.allocatable)
4808 {
4809 tree vptr;
4810
4811 if (UNLIMITED_POLY (sym))
4812 vptr = null_pointer_node;
4813 else
4814 {
4815 gfc_symbol *vsym;
4816 vsym = gfc_find_derived_vtab (sym->ts.u.derived);
4817 vptr = gfc_get_symbol_decl (sym: vsym);
4818 vptr = gfc_build_addr_expr (NULL, vptr);
4819 }
4820
4821 if (CLASS_DATA (sym)->attr.dimension
4822 || (CLASS_DATA (sym)->attr.codimension
4823 && flag_coarray != GFC_FCOARRAY_LIB))
4824 {
4825 tmp = gfc_class_data_get (sym->backend_decl);
4826 tmp = gfc_build_null_descriptor (TREE_TYPE (tmp));
4827 }
4828 else
4829 tmp = null_pointer_node;
4830
4831 DECL_INITIAL (sym->backend_decl)
4832 = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp);
4833 TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1;
4834 }
4835 else if ((sym->attr.dimension || sym->attr.codimension
4836 || (IS_CLASS_ARRAY (sym) && !CLASS_DATA (sym)->attr.allocatable)))
4837 {
4838 bool is_classarray = IS_CLASS_ARRAY (sym);
4839 symbol_attribute *array_attr;
4840 gfc_array_spec *as;
4841 array_type type_of_array;
4842
4843 array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
4844 as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
4845 /* Assumed-size Cray pointees need to be treated as AS_EXPLICIT. */
4846 type_of_array = as->type;
4847 if (type_of_array == AS_ASSUMED_SIZE && as->cp_was_assumed)
4848 type_of_array = AS_EXPLICIT;
4849 switch (type_of_array)
4850 {
4851 case AS_EXPLICIT:
4852 if (sym->attr.dummy || sym->attr.result)
4853 gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
4854 /* Allocatable and pointer arrays need to processed
4855 explicitly. */
4856 else if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
4857 || (sym->ts.type == BT_CLASS
4858 && CLASS_DATA (sym)->attr.class_pointer)
4859 || array_attr->allocatable)
4860 {
4861 if (TREE_STATIC (sym->backend_decl))
4862 {
4863 gfc_save_backend_locus (&loc);
4864 gfc_set_backend_locus (&sym->declared_at);
4865 gfc_trans_static_array_pointer (sym);
4866 gfc_restore_backend_locus (&loc);
4867 }
4868 else
4869 {
4870 seen_trans_deferred_array = true;
4871 gfc_trans_deferred_array (sym, block);
4872 }
4873 }
4874 else if (sym->attr.codimension
4875 && TREE_STATIC (sym->backend_decl))
4876 {
4877 gfc_init_block (&tmpblock);
4878 gfc_trans_array_cobounds (TREE_TYPE (sym->backend_decl),
4879 &tmpblock, sym);
4880 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock),
4881 NULL_TREE);
4882 continue;
4883 }
4884 else
4885 {
4886 gfc_save_backend_locus (&loc);
4887 gfc_set_backend_locus (&sym->declared_at);
4888
4889 if (alloc_comp_or_fini)
4890 {
4891 seen_trans_deferred_array = true;
4892 gfc_trans_deferred_array (sym, block);
4893 }
4894 else if (sym->ts.type == BT_DERIVED
4895 && sym->value
4896 && !sym->attr.data
4897 && sym->attr.save == SAVE_NONE)
4898 {
4899 gfc_start_block (&tmpblock);
4900 gfc_init_default_dt (sym, block: &tmpblock, dealloc: false);
4901 gfc_add_init_cleanup (block,
4902 init: gfc_finish_block (&tmpblock),
4903 NULL_TREE);
4904 }
4905
4906 gfc_trans_auto_array_allocation (sym->backend_decl,
4907 sym, block);
4908 gfc_restore_backend_locus (&loc);
4909 }
4910 break;
4911
4912 case AS_ASSUMED_SIZE:
4913 /* Must be a dummy parameter. */
4914 gcc_assert (sym->attr.dummy || as->cp_was_assumed);
4915
4916 /* We should always pass assumed size arrays the g77 way. */
4917 if (sym->attr.dummy)
4918 gfc_trans_g77_array (sym, block);
4919 break;
4920
4921 case AS_ASSUMED_SHAPE:
4922 /* Must be a dummy parameter. */
4923 gcc_assert (sym->attr.dummy);
4924
4925 gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
4926 break;
4927
4928 case AS_ASSUMED_RANK:
4929 case AS_DEFERRED:
4930 seen_trans_deferred_array = true;
4931 gfc_trans_deferred_array (sym, block);
4932 if (sym->ts.type == BT_CHARACTER && sym->ts.deferred
4933 && sym->attr.result)
4934 {
4935 gfc_start_block (&init);
4936 gfc_save_backend_locus (&loc);
4937 gfc_set_backend_locus (&sym->declared_at);
4938 tmp = gfc_null_and_pass_deferred_len (sym, init: &init, loc: &loc);
4939 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), cleanup: tmp);
4940 }
4941 break;
4942
4943 default:
4944 gcc_unreachable ();
4945 }
4946 if (alloc_comp_or_fini && !seen_trans_deferred_array)
4947 gfc_trans_deferred_array (sym, block);
4948 }
4949 else if ((!sym->attr.dummy || sym->ts.deferred)
4950 && (sym->ts.type == BT_CLASS
4951 && CLASS_DATA (sym)->attr.class_pointer))
4952 gfc_trans_class_array (sym, block);
4953 else if ((!sym->attr.dummy || sym->ts.deferred)
4954 && (sym->attr.allocatable
4955 || (sym->attr.pointer && sym->attr.result)
4956 || (sym->ts.type == BT_CLASS
4957 && CLASS_DATA (sym)->attr.allocatable)))
4958 {
4959 if (!sym->attr.save && flag_max_stack_var_size != 0)
4960 {
4961 tree descriptor = NULL_TREE;
4962
4963 gfc_save_backend_locus (&loc);
4964 gfc_set_backend_locus (&sym->declared_at);
4965 gfc_start_block (&init);
4966
4967 if (sym->ts.type == BT_CHARACTER
4968 && sym->attr.allocatable
4969 && !sym->attr.dimension
4970 && sym->ts.u.cl && sym->ts.u.cl->length
4971 && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE)
4972 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4973
4974 if (!sym->attr.pointer)
4975 {
4976 /* Nullify and automatic deallocation of allocatable
4977 scalars. */
4978 e = gfc_lval_expr_from_sym (sym);
4979 if (sym->ts.type == BT_CLASS)
4980 gfc_add_data_component (e);
4981
4982 gfc_init_se (&se, NULL);
4983 if (sym->ts.type != BT_CLASS
4984 || sym->ts.u.derived->attr.dimension
4985 || sym->ts.u.derived->attr.codimension)
4986 {
4987 se.want_pointer = 1;
4988 gfc_conv_expr (se: &se, expr: e);
4989 }
4990 else if (sym->ts.type == BT_CLASS
4991 && !CLASS_DATA (sym)->attr.dimension
4992 && !CLASS_DATA (sym)->attr.codimension)
4993 {
4994 se.want_pointer = 1;
4995 gfc_conv_expr (se: &se, expr: e);
4996 }
4997 else
4998 {
4999 se.descriptor_only = 1;
5000 gfc_conv_expr (se: &se, expr: e);
5001 descriptor = se.expr;
5002 se.expr = gfc_conv_descriptor_data_addr (se.expr);
5003 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
5004 }
5005 gfc_free_expr (e);
5006
5007 if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
5008 {
5009 /* Nullify when entering the scope. */
5010 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5011 TREE_TYPE (se.expr), se.expr,
5012 fold_convert (TREE_TYPE (se.expr),
5013 null_pointer_node));
5014 if (sym->attr.optional)
5015 {
5016 tree present = gfc_conv_expr_present (sym);
5017 tmp = build3_loc (loc: input_location, code: COND_EXPR,
5018 void_type_node, arg0: present, arg1: tmp,
5019 arg2: build_empty_stmt (input_location));
5020 }
5021 gfc_add_expr_to_block (&init, tmp);
5022 }
5023 }
5024
5025 if ((sym->attr.dummy || sym->attr.result)
5026 && sym->ts.type == BT_CHARACTER
5027 && sym->ts.deferred
5028 && sym->ts.u.cl->passed_length)
5029 tmp = gfc_null_and_pass_deferred_len (sym, init: &init, loc: &loc);
5030 else
5031 {
5032 gfc_restore_backend_locus (&loc);
5033 tmp = NULL_TREE;
5034 }
5035
5036 /* Initialize descriptor's TKR information. */
5037 if (sym->ts.type == BT_CLASS)
5038 gfc_trans_class_array (sym, block);
5039
5040 /* Deallocate when leaving the scope. Nullifying is not
5041 needed. */
5042 if (!sym->attr.result && !sym->attr.dummy && !sym->attr.pointer
5043 && !sym->ns->proc_name->attr.is_main_program)
5044 {
5045 if (sym->ts.type == BT_CLASS
5046 && CLASS_DATA (sym)->attr.codimension)
5047 tmp = gfc_deallocate_with_status (descriptor, NULL_TREE,
5048 NULL_TREE, NULL_TREE,
5049 NULL_TREE, true, NULL,
5050 GFC_CAF_COARRAY_ANALYZE);
5051 else
5052 {
5053 gfc_expr *expr = gfc_lval_expr_from_sym (sym);
5054 tmp = gfc_deallocate_scalar_with_status (se.expr,
5055 NULL_TREE,
5056 NULL_TREE,
5057 true, expr,
5058 sym->ts);
5059 gfc_free_expr (expr);
5060 }
5061 }
5062
5063 if (sym->ts.type == BT_CLASS)
5064 {
5065 /* Initialize _vptr to declared type. */
5066 gfc_symbol *vtab;
5067 tree rhs;
5068
5069 gfc_save_backend_locus (&loc);
5070 gfc_set_backend_locus (&sym->declared_at);
5071 e = gfc_lval_expr_from_sym (sym);
5072 gfc_add_vptr_component (e);
5073 gfc_init_se (&se, NULL);
5074 se.want_pointer = 1;
5075 gfc_conv_expr (se: &se, expr: e);
5076 gfc_free_expr (e);
5077 if (UNLIMITED_POLY (sym))
5078 rhs = build_int_cst (TREE_TYPE (se.expr), 0);
5079 else
5080 {
5081 vtab = gfc_find_derived_vtab (sym->ts.u.derived);
5082 rhs = gfc_build_addr_expr (TREE_TYPE (se.expr),
5083 gfc_get_symbol_decl (sym: vtab));
5084 }
5085 gfc_add_modify (&init, se.expr, rhs);
5086 gfc_restore_backend_locus (&loc);
5087 }
5088
5089 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), cleanup: tmp);
5090 }
5091 }
5092 else if (sym->ts.type == BT_CHARACTER && sym->ts.deferred)
5093 {
5094 tree tmp = NULL;
5095 stmtblock_t init;
5096
5097 /* If we get to here, all that should be left are pointers. */
5098 gcc_assert (sym->attr.pointer);
5099
5100 if (sym->attr.dummy)
5101 {
5102 gfc_start_block (&init);
5103 gfc_save_backend_locus (&loc);
5104 gfc_set_backend_locus (&sym->declared_at);
5105 tmp = gfc_null_and_pass_deferred_len (sym, init: &init, loc: &loc);
5106 gfc_add_init_cleanup (block, init: gfc_finish_block (&init), cleanup: tmp);
5107 }
5108 }
5109 else if (sym->ts.deferred)
5110 gfc_fatal_error ("Deferred type parameter not yet supported");
5111 else if (alloc_comp_or_fini)
5112 gfc_trans_deferred_array (sym, block);
5113 else if (sym->ts.type == BT_CHARACTER)
5114 {
5115 gfc_save_backend_locus (&loc);
5116 gfc_set_backend_locus (&sym->declared_at);
5117 if (sym->attr.dummy || sym->attr.result)
5118 gfc_trans_dummy_character (sym, cl: sym->ts.u.cl, block);
5119 else
5120 gfc_trans_auto_character_variable (sym, block);
5121 gfc_restore_backend_locus (&loc);
5122 }
5123 else if (sym->attr.assign)
5124 {
5125 gfc_save_backend_locus (&loc);
5126 gfc_set_backend_locus (&sym->declared_at);
5127 gfc_trans_assign_aux_var (sym, block);
5128 gfc_restore_backend_locus (&loc);
5129 }
5130 else if (sym->ts.type == BT_DERIVED
5131 && sym->value
5132 && !sym->attr.data
5133 && sym->attr.save == SAVE_NONE)
5134 {
5135 gfc_start_block (&tmpblock);
5136 gfc_init_default_dt (sym, block: &tmpblock, dealloc: false);
5137 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock),
5138 NULL_TREE);
5139 }
5140 else if (!(UNLIMITED_POLY(sym)) && !is_pdt_type)
5141 gcc_unreachable ();
5142 }
5143
5144 /* Handle 'omp allocate'. This has to be after the block above as
5145 gfc_add_init_cleanup (..., init, ...) puts 'init' of later calls
5146 before earlier calls. The code is a bit more complex as gfortran does
5147 not really work with bind expressions / BIND_EXPR_VARS properly, i.e.
5148 gimplify_bind_expr needs some help for placing the GOMP_alloc. Thus,
5149 we pass on the location of the allocate-assignment expression and,
5150 if the size is not constant, the size variable if Fortran computes this
5151 differently. We also might add an expression location after which the
5152 code has to be added, e.g. for character len expressions, which affect
5153 the UNIT_SIZE. */
5154 gfc_expr *last_allocator = NULL;
5155 if (omp_ns && omp_ns->omp_allocate)
5156 {
5157 if (!block->init || TREE_CODE (block->init) != STATEMENT_LIST)
5158 {
5159 tree tmp = build1_v (LABEL_EXPR, gfc_build_label_decl (NULL_TREE));
5160 append_to_statement_list (tmp, &block->init);
5161 }
5162 if (!block->cleanup || TREE_CODE (block->cleanup) != STATEMENT_LIST)
5163 {
5164 tree tmp = build1_v (LABEL_EXPR, gfc_build_label_decl (NULL_TREE));
5165 append_to_statement_list (tmp, &block->cleanup);
5166 }
5167 }
5168 tree init_stmtlist = block->init;
5169 tree cleanup_stmtlist = block->cleanup;
5170 se.expr = NULL_TREE;
5171 for (struct gfc_omp_namelist *n = omp_ns ? omp_ns->omp_allocate : NULL;
5172 n; n = n->next)
5173 if (!TREE_STATIC (n->sym->backend_decl))
5174 {
5175 tree align = (n->u.align ? gfc_conv_constant_to_tree (n->u.align)
5176 : NULL_TREE);
5177 if (last_allocator != n->u2.allocator)
5178 {
5179 location_t loc = input_location;
5180 gfc_init_se (&se, NULL);
5181 if (n->u2.allocator)
5182 {
5183 input_location = gfc_get_location (&n->u2.allocator->where);
5184 gfc_conv_expr (se: &se, expr: n->u2.allocator);
5185 }
5186 /* We need to evalulate non-constants - also to find the location
5187 after which the GOMP_alloc has to be added to - also as BLOCK
5188 does not yield a new BIND_EXPR_BODY. */
5189 if (n->u2.allocator
5190 && (!(CONSTANT_CLASS_P (se.expr) && DECL_P (se.expr))
5191 || se.pre.head || se.post.head))
5192 {
5193 stmtblock_t tmpblock;
5194 gfc_init_block (&tmpblock);
5195 se.expr = gfc_evaluate_now (se.expr, &tmpblock);
5196 /* First post then pre because the new code is inserted
5197 at the top. */
5198 gfc_add_init_cleanup (block, init: gfc_finish_block (&se.post), NULL);
5199 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock),
5200 NULL);
5201 gfc_add_init_cleanup (block, init: gfc_finish_block (&se.pre), NULL);
5202 }
5203 last_allocator = n->u2.allocator;
5204 input_location = loc;
5205 }
5206
5207 /* 'omp allocate( {purpose: allocator, value: align},
5208 {purpose: init-stmtlist, value: cleanup-stmtlist},
5209 {purpose: size-var, value: last-size-expr}}
5210 where init-stmt/cleanup-stmt is the STATEMENT list to find the
5211 try-final block; last-size-expr is to find the location after
5212 which to add the code and 'size-var' is for the proper size, cf.
5213 gfc_trans_auto_array_allocation - either or both of the latter
5214 can be NULL. */
5215 tree tmp = lookup_attribute (attr_name: "omp allocate",
5216 DECL_ATTRIBUTES (n->sym->backend_decl));
5217 tmp = TREE_VALUE (tmp);
5218 TREE_PURPOSE (tmp) = se.expr;
5219 TREE_VALUE (tmp) = align;
5220 TREE_PURPOSE (TREE_CHAIN (tmp)) = init_stmtlist;
5221 TREE_VALUE (TREE_CHAIN (tmp)) = cleanup_stmtlist;
5222 }
5223 else if (n->sym->attr.in_common)
5224 {
5225 gfc_error ("Sorry, !$OMP allocate for COMMON block variable %qs at %L "
5226 "not supported", n->sym->common_block->name,
5227 &n->sym->common_block->where);
5228 break;
5229 }
5230 else
5231 {
5232 gfc_error ("Sorry, !$OMP allocate for variable %qs at %L with SAVE "
5233 "attribute not yet implemented", n->sym->name,
5234 &n->sym->declared_at);
5235 /* FIXME: Remember to handle last_allocator. */
5236 break;
5237 }
5238
5239 gfc_init_block (&tmpblock);
5240
5241 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
5242 {
5243 if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER
5244 && f->sym->ts.u.cl->backend_decl)
5245 {
5246 if (TREE_CODE (f->sym->ts.u.cl->backend_decl) == PARM_DECL)
5247 gfc_trans_vla_type_sizes (sym: f->sym, body: &tmpblock);
5248 }
5249 }
5250
5251 if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
5252 && current_fake_result_decl != NULL)
5253 {
5254 gcc_assert (proc_sym->ts.u.cl->backend_decl != NULL);
5255 if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == PARM_DECL)
5256 gfc_trans_vla_type_sizes (sym: proc_sym, body: &tmpblock);
5257 }
5258
5259 gfc_add_init_cleanup (block, init: gfc_finish_block (&tmpblock), NULL_TREE);
5260}
5261
5262
5263struct module_hasher : ggc_ptr_hash<module_htab_entry>
5264{
5265 typedef const char *compare_type;
5266
5267 static hashval_t hash (module_htab_entry *s)
5268 {
5269 return htab_hash_string (s->name);
5270 }
5271
5272 static bool
5273 equal (module_htab_entry *a, const char *b)
5274 {
5275 return !strcmp (s1: a->name, s2: b);
5276 }
5277};
5278
5279static GTY (()) hash_table<module_hasher> *module_htab;
5280
5281/* Hash and equality functions for module_htab's decls. */
5282
5283hashval_t
5284module_decl_hasher::hash (tree t)
5285{
5286 const_tree n = DECL_NAME (t);
5287 if (n == NULL_TREE)
5288 n = TYPE_NAME (TREE_TYPE (t));
5289 return htab_hash_string (IDENTIFIER_POINTER (n));
5290}
5291
5292bool
5293module_decl_hasher::equal (tree t1, const char *x2)
5294{
5295 const_tree n1 = DECL_NAME (t1);
5296 if (n1 == NULL_TREE)
5297 n1 = TYPE_NAME (TREE_TYPE (t1));
5298 return strcmp (IDENTIFIER_POINTER (n1), s2: x2) == 0;
5299}
5300
5301struct module_htab_entry *
5302gfc_find_module (const char *name)
5303{
5304 if (! module_htab)
5305 module_htab = hash_table<module_hasher>::create_ggc (n: 10);
5306
5307 module_htab_entry **slot
5308 = module_htab->find_slot_with_hash (comparable: name, hash: htab_hash_string (name), insert: INSERT);
5309 if (*slot == NULL)
5310 {
5311 module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
5312
5313 entry->name = gfc_get_string ("%s", name);
5314 entry->decls = hash_table<module_decl_hasher>::create_ggc (n: 10);
5315 *slot = entry;
5316 }
5317 return *slot;
5318}
5319
5320void
5321gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
5322{
5323 const char *name;
5324
5325 if (DECL_NAME (decl))
5326 name = IDENTIFIER_POINTER (DECL_NAME (decl));
5327 else
5328 {
5329 gcc_assert (TREE_CODE (decl) == TYPE_DECL);
5330 name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
5331 }
5332 tree *slot
5333 = entry->decls->find_slot_with_hash (comparable: name, hash: htab_hash_string (name),
5334 insert: INSERT);
5335 if (*slot == NULL)
5336 *slot = decl;
5337}
5338
5339
5340/* Generate debugging symbols for namelists. This function must come after
5341 generate_local_decl to ensure that the variables in the namelist are
5342 already declared. */
5343
5344static tree
5345generate_namelist_decl (gfc_symbol * sym)
5346{
5347 gfc_namelist *nml;
5348 tree decl;
5349 vec<constructor_elt, va_gc> *nml_decls = NULL;
5350
5351 gcc_assert (sym->attr.flavor == FL_NAMELIST);
5352 for (nml = sym->namelist; nml; nml = nml->next)
5353 {
5354 if (nml->sym->backend_decl == NULL_TREE)
5355 {
5356 nml->sym->attr.referenced = 1;
5357 nml->sym->backend_decl = gfc_get_symbol_decl (sym: nml->sym);
5358 }
5359 DECL_IGNORED_P (nml->sym->backend_decl) = 0;
5360 CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
5361 }
5362
5363 decl = make_node (NAMELIST_DECL);
5364 TREE_TYPE (decl) = void_type_node;
5365 NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
5366 DECL_NAME (decl) = get_identifier (sym->name);
5367 return decl;
5368}
5369
5370
5371/* Output an initialized decl for a module variable. */
5372
5373static void
5374gfc_create_module_variable (gfc_symbol * sym)
5375{
5376 tree decl;
5377
5378 /* Module functions with alternate entries are dealt with later and
5379 would get caught by the next condition. */
5380 if (sym->attr.entry)
5381 return;
5382
5383 /* Make sure we convert the types of the derived types from iso_c_binding
5384 into (void *). */
5385 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
5386 && sym->ts.type == BT_DERIVED)
5387 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
5388
5389 if (gfc_fl_struct (sym->attr.flavor)
5390 && sym->backend_decl
5391 && TREE_CODE (sym->backend_decl) == RECORD_TYPE)
5392 {
5393 decl = sym->backend_decl;
5394 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5395
5396 if (!sym->attr.use_assoc && !sym->attr.used_in_submodule)
5397 {
5398 gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE
5399 || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl);
5400 gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE
5401 || DECL_CONTEXT (TYPE_STUB_DECL (decl))
5402 == sym->ns->proc_name->backend_decl);
5403 }
5404 TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5405 DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl;
5406 gfc_module_add_decl (entry: cur_module, TYPE_STUB_DECL (decl));
5407 }
5408
5409 /* Only output variables, procedure pointers and array valued,
5410 or derived type, parameters. */
5411 if (sym->attr.flavor != FL_VARIABLE
5412 && !(sym->attr.flavor == FL_PARAMETER
5413 && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
5414 && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer))
5415 return;
5416
5417 if ((sym->attr.in_common || sym->attr.in_equivalence) && sym->backend_decl)
5418 {
5419 decl = sym->backend_decl;
5420 gcc_assert (DECL_FILE_SCOPE_P (decl));
5421 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5422 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5423 gfc_module_add_decl (entry: cur_module, decl);
5424 }
5425
5426 /* Don't generate variables from other modules. Variables from
5427 COMMONs and Cray pointees will already have been generated. */
5428 if (sym->attr.use_assoc || sym->attr.used_in_submodule
5429 || sym->attr.in_common || sym->attr.cray_pointee)
5430 return;
5431
5432 /* Equivalenced variables arrive here after creation. */
5433 if (sym->backend_decl
5434 && (sym->equiv_built || sym->attr.in_equivalence))
5435 return;
5436
5437 if (sym->backend_decl && !sym->attr.vtab && !sym->attr.target)
5438 gfc_internal_error ("backend decl for module variable %qs already exists",
5439 sym->name);
5440
5441 if (sym->module && !sym->attr.result && !sym->attr.dummy
5442 && (sym->attr.access == ACCESS_UNKNOWN
5443 && (sym->ns->default_access == ACCESS_PRIVATE
5444 || (sym->ns->default_access == ACCESS_UNKNOWN
5445 && flag_module_private))))
5446 sym->attr.access = ACCESS_PRIVATE;
5447
5448 if (warn_unused_variable && !sym->attr.referenced
5449 && sym->attr.access == ACCESS_PRIVATE)
5450 gfc_warning (opt: OPT_Wunused_value,
5451 "Unused PRIVATE module variable %qs declared at %L",
5452 sym->name, &sym->declared_at);
5453
5454 /* We always want module variables to be created. */
5455 sym->attr.referenced = 1;
5456 /* Create the decl. */
5457 decl = gfc_get_symbol_decl (sym);
5458
5459 /* Create the variable. */
5460 pushdecl (decl);
5461 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
5462 || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
5463 && sym->fn_result_spec));
5464 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5465 rest_of_decl_compilation (decl, 1, 0);
5466 gfc_module_add_decl (entry: cur_module, decl);
5467
5468 /* Also add length of strings. */
5469 if (sym->ts.type == BT_CHARACTER)
5470 {
5471 tree length;
5472
5473 length = sym->ts.u.cl->backend_decl;
5474 gcc_assert (length || sym->attr.proc_pointer);
5475 if (length && !INTEGER_CST_P (length))
5476 {
5477 pushdecl (length);
5478 rest_of_decl_compilation (length, 1, 0);
5479 }
5480 }
5481
5482 if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
5483 && sym->attr.referenced && !sym->attr.use_assoc)
5484 has_coarray_vars = true;
5485}
5486
5487/* Emit debug information for USE statements. */
5488
5489static void
5490gfc_trans_use_stmts (gfc_namespace * ns)
5491{
5492 gfc_use_list *use_stmt;
5493 for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next)
5494 {
5495 struct module_htab_entry *entry
5496 = gfc_find_module (name: use_stmt->module_name);
5497 gfc_use_rename *rent;
5498
5499 if (entry->namespace_decl == NULL)
5500 {
5501 entry->namespace_decl
5502 = build_decl (input_location,
5503 NAMESPACE_DECL,
5504 get_identifier (use_stmt->module_name),
5505 void_type_node);
5506 DECL_EXTERNAL (entry->namespace_decl) = 1;
5507 }
5508 gfc_set_backend_locus (&use_stmt->where);
5509 if (!use_stmt->only_flag)
5510 (*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
5511 NULL_TREE,
5512 ns->proc_name->backend_decl,
5513 false, false);
5514 for (rent = use_stmt->rename; rent; rent = rent->next)
5515 {
5516 tree decl, local_name;
5517
5518 if (rent->op != INTRINSIC_NONE)
5519 continue;
5520
5521 hashval_t hash = htab_hash_string (rent->use_name);
5522 tree *slot = entry->decls->find_slot_with_hash (comparable: rent->use_name, hash,
5523 insert: INSERT);
5524 if (*slot == NULL)
5525 {
5526 gfc_symtree *st;
5527
5528 st = gfc_find_symtree (ns->sym_root,
5529 rent->local_name[0]
5530 ? rent->local_name : rent->use_name);
5531
5532 /* The following can happen if a derived type is renamed. */
5533 if (!st)
5534 {
5535 char *name;
5536 name = xstrdup (rent->local_name[0]
5537 ? rent->local_name : rent->use_name);
5538 name[0] = (char) TOUPPER ((unsigned char) name[0]);
5539 st = gfc_find_symtree (ns->sym_root, name);
5540 free (ptr: name);
5541 gcc_assert (st);
5542 }
5543
5544 /* Sometimes, generic interfaces wind up being over-ruled by a
5545 local symbol (see PR41062). */
5546 if (!st->n.sym->attr.use_assoc)
5547 {
5548 *slot = error_mark_node;
5549 entry->decls->clear_slot (slot);
5550 continue;
5551 }
5552
5553 if (st->n.sym->backend_decl
5554 && DECL_P (st->n.sym->backend_decl)
5555 && st->n.sym->module
5556 && strcmp (s1: st->n.sym->module, s2: use_stmt->module_name) == 0)
5557 {
5558 gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
5559 || !VAR_P (st->n.sym->backend_decl));
5560 decl = copy_node (st->n.sym->backend_decl);
5561 DECL_CONTEXT (decl) = entry->namespace_decl;
5562 DECL_EXTERNAL (decl) = 1;
5563 DECL_IGNORED_P (decl) = 0;
5564 DECL_INITIAL (decl) = NULL_TREE;
5565 }
5566 else if (st->n.sym->attr.flavor == FL_NAMELIST
5567 && st->n.sym->attr.use_only
5568 && st->n.sym->module
5569 && strcmp (s1: st->n.sym->module, s2: use_stmt->module_name)
5570 == 0)
5571 {
5572 decl = generate_namelist_decl (sym: st->n.sym);
5573 DECL_CONTEXT (decl) = entry->namespace_decl;
5574 DECL_EXTERNAL (decl) = 1;
5575 DECL_IGNORED_P (decl) = 0;
5576 DECL_INITIAL (decl) = NULL_TREE;
5577 }
5578 else
5579 {
5580 *slot = error_mark_node;
5581 entry->decls->clear_slot (slot);
5582 continue;
5583 }
5584 *slot = decl;
5585 }
5586 decl = (tree) *slot;
5587 if (rent->local_name[0])
5588 local_name = get_identifier (rent->local_name);
5589 else
5590 local_name = NULL_TREE;
5591 gfc_set_backend_locus (&rent->where);
5592 (*debug_hooks->imported_module_or_decl) (decl, local_name,
5593 ns->proc_name->backend_decl,
5594 !use_stmt->only_flag,
5595 false);
5596 }
5597 }
5598}
5599
5600
5601/* Return true if expr is a constant initializer that gfc_conv_initializer
5602 will handle. */
5603
5604static bool
5605check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
5606 bool pointer)
5607{
5608 gfc_constructor *c;
5609 gfc_component *cm;
5610
5611 if (pointer)
5612 return true;
5613 else if (array)
5614 {
5615 if (expr->expr_type == EXPR_CONSTANT || expr->expr_type == EXPR_NULL)
5616 return true;
5617 else if (expr->expr_type == EXPR_STRUCTURE)
5618 return check_constant_initializer (expr, ts, array: false, pointer: false);
5619 else if (expr->expr_type != EXPR_ARRAY)
5620 return false;
5621 for (c = gfc_constructor_first (base: expr->value.constructor);
5622 c; c = gfc_constructor_next (ctor: c))
5623 {
5624 if (c->iterator)
5625 return false;
5626 if (c->expr->expr_type == EXPR_STRUCTURE)
5627 {
5628 if (!check_constant_initializer (expr: c->expr, ts, array: false, pointer: false))
5629 return false;
5630 }
5631 else if (c->expr->expr_type != EXPR_CONSTANT)
5632 return false;
5633 }
5634 return true;
5635 }
5636 else switch (ts->type)
5637 {
5638 case_bt_struct:
5639 if (expr->expr_type != EXPR_STRUCTURE)
5640 return false;
5641 cm = expr->ts.u.derived->components;
5642 for (c = gfc_constructor_first (base: expr->value.constructor);
5643 c; c = gfc_constructor_next (ctor: c), cm = cm->next)
5644 {
5645 if (!c->expr || cm->attr.allocatable)
5646 continue;
5647 if (!check_constant_initializer (expr: c->expr, ts: &cm->ts,
5648 array: cm->attr.dimension,
5649 pointer: cm->attr.pointer))
5650 return false;
5651 }
5652 return true;
5653 default:
5654 return expr->expr_type == EXPR_CONSTANT;
5655 }
5656}
5657
5658/* Emit debug info for parameters and unreferenced variables with
5659 initializers. */
5660
5661static void
5662gfc_emit_parameter_debug_info (gfc_symbol *sym)
5663{
5664 tree decl;
5665
5666 if (sym->attr.flavor != FL_PARAMETER
5667 && (sym->attr.flavor != FL_VARIABLE || sym->attr.referenced))
5668 return;
5669
5670 if (sym->backend_decl != NULL
5671 || sym->value == NULL
5672 || sym->attr.use_assoc
5673 || sym->attr.dummy
5674 || sym->attr.result
5675 || sym->attr.function
5676 || sym->attr.intrinsic
5677 || sym->attr.pointer
5678 || sym->attr.allocatable
5679 || sym->attr.cray_pointee
5680 || sym->attr.threadprivate
5681 || sym->attr.is_bind_c
5682 || sym->attr.subref_array_pointer
5683 || sym->attr.assign)
5684 return;
5685
5686 if (sym->ts.type == BT_CHARACTER)
5687 {
5688 gfc_conv_const_charlen (sym->ts.u.cl);
5689 if (sym->ts.u.cl->backend_decl == NULL
5690 || TREE_CODE (sym->ts.u.cl->backend_decl) != INTEGER_CST)
5691 return;
5692 }
5693 else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp)
5694 return;
5695
5696 if (sym->as)
5697 {
5698 int n;
5699
5700 if (sym->as->type != AS_EXPLICIT)
5701 return;
5702 for (n = 0; n < sym->as->rank; n++)
5703 if (sym->as->lower[n]->expr_type != EXPR_CONSTANT
5704 || sym->as->upper[n] == NULL
5705 || sym->as->upper[n]->expr_type != EXPR_CONSTANT)
5706 return;
5707 }
5708
5709 if (!check_constant_initializer (expr: sym->value, ts: &sym->ts,
5710 array: sym->attr.dimension, pointer: false))
5711 return;
5712
5713 if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
5714 return;
5715
5716 /* Create the decl for the variable or constant. */
5717 decl = build_decl (input_location,
5718 sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
5719 gfc_sym_identifier (sym), gfc_sym_type (sym));
5720 if (sym->attr.flavor == FL_PARAMETER)
5721 TREE_READONLY (decl) = 1;
5722 gfc_set_decl_location (decl, loc: &sym->declared_at);
5723 if (sym->attr.dimension)
5724 GFC_DECL_PACKED_ARRAY (decl) = 1;
5725 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5726 TREE_STATIC (decl) = 1;
5727 TREE_USED (decl) = 1;
5728 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
5729 TREE_PUBLIC (decl) = 1;
5730 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
5731 TREE_TYPE (decl),
5732 sym->attr.dimension,
5733 false, false);
5734 debug_hooks->early_global_decl (decl);
5735}
5736
5737
5738static void
5739generate_coarray_sym_init (gfc_symbol *sym)
5740{
5741 tree tmp, size, decl, token, desc;
5742 bool is_lock_type, is_event_type;
5743 int reg_type;
5744 gfc_se se;
5745 symbol_attribute attr;
5746
5747 if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
5748 || sym->attr.use_assoc || !sym->attr.referenced
5749 || sym->attr.associate_var
5750 || sym->attr.select_type_temporary)
5751 return;
5752
5753 decl = sym->backend_decl;
5754 TREE_USED(decl) = 1;
5755 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
5756
5757 is_lock_type = sym->ts.type == BT_DERIVED
5758 && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5759 && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE;
5760
5761 is_event_type = sym->ts.type == BT_DERIVED
5762 && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5763 && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE;
5764
5765 /* FIXME: Workaround for PR middle-end/49106, cf. also PR middle-end/49108
5766 to make sure the variable is not optimized away. */
5767 DECL_PRESERVE_P (DECL_CONTEXT (decl)) = 1;
5768
5769 /* For lock types, we pass the array size as only the library knows the
5770 size of the variable. */
5771 if (is_lock_type || is_event_type)
5772 size = gfc_index_one_node;
5773 else
5774 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (decl)));
5775
5776 /* Ensure that we do not have size=0 for zero-sized arrays. */
5777 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
5778 fold_convert (size_type_node, size),
5779 build_int_cst (size_type_node, 1));
5780
5781 if (GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)))
5782 {
5783 tmp = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (decl));
5784 size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5785 fold_convert (size_type_node, tmp), size);
5786 }
5787
5788 gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (decl)) != NULL_TREE);
5789 token = gfc_build_addr_expr (ppvoid_type_node,
5790 GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE(decl)));
5791 if (is_lock_type)
5792 reg_type = sym->attr.artificial ? GFC_CAF_CRITICAL : GFC_CAF_LOCK_STATIC;
5793 else if (is_event_type)
5794 reg_type = GFC_CAF_EVENT_STATIC;
5795 else
5796 reg_type = GFC_CAF_COARRAY_STATIC;
5797
5798 /* Compile the symbol attribute. */
5799 if (sym->ts.type == BT_CLASS)
5800 {
5801 attr = CLASS_DATA (sym)->attr;
5802 /* The pointer attribute is always set on classes, overwrite it with the
5803 class_pointer attribute, which denotes the pointer for classes. */
5804 attr.pointer = attr.class_pointer;
5805 }
5806 else
5807 attr = sym->attr;
5808 gfc_init_se (&se, NULL);
5809 desc = gfc_conv_scalar_to_descriptor (&se, decl, attr);
5810 gfc_add_block_to_block (&caf_init_block, &se.pre);
5811
5812 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 7, size,
5813 build_int_cst (integer_type_node, reg_type),
5814 token, gfc_build_addr_expr (pvoid_type_node, desc),
5815 null_pointer_node, /* stat. */
5816 null_pointer_node, /* errgmsg. */
5817 build_zero_cst (size_type_node)); /* errmsg_len. */
5818 gfc_add_expr_to_block (&caf_init_block, tmp);
5819 gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl),
5820 gfc_conv_descriptor_data_get (desc)));
5821
5822 /* Handle "static" initializer. */
5823 if (sym->value)
5824 {
5825 if (sym->value->expr_type == EXPR_ARRAY)
5826 {
5827 gfc_constructor *c, *cnext;
5828
5829 /* Test if the array has more than one element. */
5830 c = gfc_constructor_first (base: sym->value->value.constructor);
5831 gcc_assert (c); /* Empty constructor should not happen here. */
5832 cnext = gfc_constructor_next (ctor: c);
5833
5834 if (cnext)
5835 {
5836 /* An EXPR_ARRAY with a rank > 1 here has to come from a
5837 DATA statement. Set its rank here as not to confuse
5838 the following steps. */
5839 sym->value->rank = 1;
5840 }
5841 else
5842 {
5843 /* There is only a single value in the constructor, use
5844 it directly for the assignment. */
5845 gfc_expr *new_expr;
5846 new_expr = gfc_copy_expr (c->expr);
5847 gfc_free_expr (sym->value);
5848 sym->value = new_expr;
5849 }
5850 }
5851
5852 sym->attr.pointer = 1;
5853 tmp = gfc_trans_assignment (gfc_lval_expr_from_sym (sym), sym->value,
5854 true, false);
5855 sym->attr.pointer = 0;
5856 gfc_add_expr_to_block (&caf_init_block, tmp);
5857 }
5858 else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pointer_comp)
5859 {
5860 tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, decl, sym->as
5861 ? sym->as->rank : 0,
5862 cm: GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
5863 gfc_add_expr_to_block (&caf_init_block, tmp);
5864 }
5865}
5866
5867
5868/* Generate constructor function to initialize static, nonallocatable
5869 coarrays. */
5870
5871static void
5872generate_coarray_init (gfc_namespace * ns __attribute((unused)))
5873{
5874 tree fndecl, tmp, decl, save_fn_decl;
5875
5876 save_fn_decl = current_function_decl;
5877 push_function_context ();
5878
5879 tmp = build_function_type_list (void_type_node, NULL_TREE);
5880 fndecl = build_decl (input_location, FUNCTION_DECL,
5881 create_tmp_var_name ("_caf_init"), tmp);
5882
5883 DECL_STATIC_CONSTRUCTOR (fndecl) = 1;
5884 SET_DECL_INIT_PRIORITY (fndecl, DEFAULT_INIT_PRIORITY);
5885
5886 decl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node);
5887 DECL_ARTIFICIAL (decl) = 1;
5888 DECL_IGNORED_P (decl) = 1;
5889 DECL_CONTEXT (decl) = fndecl;
5890 DECL_RESULT (fndecl) = decl;
5891
5892 pushdecl (fndecl);
5893 current_function_decl = fndecl;
5894 announce_function (fndecl);
5895
5896 rest_of_decl_compilation (fndecl, 0, 0);
5897 make_decl_rtl (fndecl);
5898 allocate_struct_function (fndecl, false);
5899
5900 pushlevel ();
5901 gfc_init_block (&caf_init_block);
5902
5903 gfc_traverse_ns (ns, generate_coarray_sym_init);
5904
5905 DECL_SAVED_TREE (fndecl) = gfc_finish_block (&caf_init_block);
5906 decl = getdecls ();
5907
5908 poplevel (1, 1);
5909 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5910
5911 DECL_SAVED_TREE (fndecl)
5912 = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
5913 decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
5914 dump_function (phase: TDI_original, fn: fndecl);
5915
5916 cfun->function_end_locus = input_location;
5917 set_cfun (NULL);
5918
5919 if (decl_function_context (fndecl))
5920 (void) cgraph_node::create (decl: fndecl);
5921 else
5922 cgraph_node::finalize_function (fndecl, true);
5923
5924 pop_function_context ();
5925 current_function_decl = save_fn_decl;
5926}
5927
5928
5929static void
5930create_module_nml_decl (gfc_symbol *sym)
5931{
5932 if (sym->attr.flavor == FL_NAMELIST)
5933 {
5934 tree decl = generate_namelist_decl (sym);
5935 pushdecl (decl);
5936 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5937 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5938 rest_of_decl_compilation (decl, 1, 0);
5939 gfc_module_add_decl (entry: cur_module, decl);
5940 }
5941}
5942
5943
5944/* Generate all the required code for module variables. */
5945
5946void
5947gfc_generate_module_vars (gfc_namespace * ns)
5948{
5949 module_namespace = ns;
5950 cur_module = gfc_find_module (name: ns->proc_name->name);
5951
5952 /* Check if the frontend left the namespace in a reasonable state. */
5953 gcc_assert (ns->proc_name && !ns->proc_name->tlink);
5954
5955 /* Generate COMMON blocks. */
5956 gfc_trans_common (ns);
5957
5958 has_coarray_vars = false;
5959
5960 /* Create decls for all the module variables. */
5961 gfc_traverse_ns (ns, gfc_create_module_variable);
5962 gfc_traverse_ns (ns, create_module_nml_decl);
5963
5964 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
5965 generate_coarray_init (ns);
5966
5967 cur_module = NULL;
5968
5969 gfc_trans_use_stmts (ns);
5970 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
5971}
5972
5973
5974static void
5975gfc_generate_contained_functions (gfc_namespace * parent)
5976{
5977 gfc_namespace *ns;
5978
5979 /* We create all the prototypes before generating any code. */
5980 for (ns = parent->contained; ns; ns = ns->sibling)
5981 {
5982 /* Skip namespaces from used modules. */
5983 if (ns->parent != parent)
5984 continue;
5985
5986 gfc_create_function_decl (ns, global: false);
5987 }
5988
5989 for (ns = parent->contained; ns; ns = ns->sibling)
5990 {
5991 /* Skip namespaces from used modules. */
5992 if (ns->parent != parent)
5993 continue;
5994
5995 gfc_generate_function_code (ns);
5996 }
5997}
5998
5999
6000/* Drill down through expressions for the array specification bounds and
6001 character length calling generate_local_decl for all those variables
6002 that have not already been declared. */
6003
6004static void
6005generate_local_decl (gfc_symbol *);
6006
6007/* Traverse expr, marking all EXPR_VARIABLE symbols referenced. */
6008
6009static bool
6010expr_decls (gfc_expr *e, gfc_symbol *sym,
6011 int *f ATTRIBUTE_UNUSED)
6012{
6013 if (e->expr_type != EXPR_VARIABLE
6014 || sym == e->symtree->n.sym
6015 || e->symtree->n.sym->mark
6016 || e->symtree->n.sym->ns != sym->ns)
6017 return false;
6018
6019 generate_local_decl (e->symtree->n.sym);
6020 return false;
6021}
6022
6023static void
6024generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
6025{
6026 gfc_traverse_expr (e, sym, expr_decls, 0);
6027}
6028
6029
6030/* Check for dependencies in the character length and array spec. */
6031
6032static void
6033generate_dependency_declarations (gfc_symbol *sym)
6034{
6035 int i;
6036
6037 if (sym->ts.type == BT_CHARACTER
6038 && sym->ts.u.cl
6039 && sym->ts.u.cl->length
6040 && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6041 generate_expr_decls (sym, e: sym->ts.u.cl->length);
6042
6043 if (sym->as && sym->as->rank)
6044 {
6045 for (i = 0; i < sym->as->rank; i++)
6046 {
6047 generate_expr_decls (sym, e: sym->as->lower[i]);
6048 generate_expr_decls (sym, e: sym->as->upper[i]);
6049 }
6050 }
6051}
6052
6053
6054/* Generate decls for all local variables. We do this to ensure correct
6055 handling of expressions which only appear in the specification of
6056 other functions. */
6057
6058static void
6059generate_local_decl (gfc_symbol * sym)
6060{
6061 if (sym->attr.flavor == FL_VARIABLE)
6062 {
6063 if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
6064 && sym->attr.referenced && !sym->attr.use_assoc)
6065 has_coarray_vars = true;
6066
6067 if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
6068 generate_dependency_declarations (sym);
6069
6070 if (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK))
6071 {
6072 if (sym->attr.dummy)
6073 gfc_error ("Symbol %qs at %L has the WEAK attribute but is a "
6074 "dummy argument", sym->name, &sym->declared_at);
6075 else
6076 gfc_error ("Symbol %qs at %L has the WEAK attribute but is a "
6077 "local variable", sym->name, &sym->declared_at);
6078 }
6079
6080 if (sym->attr.referenced)
6081 gfc_get_symbol_decl (sym);
6082
6083 /* Warnings for unused dummy arguments. */
6084 else if (sym->attr.dummy && !sym->attr.in_namelist)
6085 {
6086 /* INTENT(out) dummy arguments are likely meant to be set. */
6087 if (warn_unused_dummy_argument && sym->attr.intent == INTENT_OUT)
6088 {
6089 if (sym->ts.type != BT_DERIVED)
6090 gfc_warning (opt: OPT_Wunused_dummy_argument,
6091 "Dummy argument %qs at %L was declared "
6092 "INTENT(OUT) but was not set", sym->name,
6093 &sym->declared_at);
6094 else if (!gfc_has_default_initializer (sym->ts.u.derived)
6095 && !sym->ts.u.derived->attr.zero_comp)
6096 gfc_warning (opt: OPT_Wunused_dummy_argument,
6097 "Derived-type dummy argument %qs at %L was "
6098 "declared INTENT(OUT) but was not set and "
6099 "does not have a default initializer",
6100 sym->name, &sym->declared_at);
6101 if (sym->backend_decl != NULL_TREE)
6102 suppress_warning (sym->backend_decl);
6103 }
6104 else if (warn_unused_dummy_argument)
6105 {
6106 if (!sym->attr.artificial)
6107 gfc_warning (opt: OPT_Wunused_dummy_argument,
6108 "Unused dummy argument %qs at %L", sym->name,
6109 &sym->declared_at);
6110
6111 if (sym->backend_decl != NULL_TREE)
6112 suppress_warning (sym->backend_decl);
6113 }
6114 }
6115
6116 /* Warn for unused variables, but not if they're inside a common
6117 block or a namelist. */
6118 else if (warn_unused_variable
6119 && !(sym->attr.in_common || sym->mark || sym->attr.in_namelist))
6120 {
6121 if (sym->attr.use_only)
6122 {
6123 gfc_warning (opt: OPT_Wunused_variable,
6124 "Unused module variable %qs which has been "
6125 "explicitly imported at %L", sym->name,
6126 &sym->declared_at);
6127 if (sym->backend_decl != NULL_TREE)
6128 suppress_warning (sym->backend_decl);
6129 }
6130 else if (!sym->attr.use_assoc)
6131 {
6132 /* Corner case: the symbol may be an entry point. At this point,
6133 it may appear to be an unused variable. Suppress warning. */
6134 bool enter = false;
6135 gfc_entry_list *el;
6136
6137 for (el = sym->ns->entries; el; el=el->next)
6138 if (strcmp(s1: sym->name, s2: el->sym->name) == 0)
6139 enter = true;
6140
6141 if (!enter)
6142 gfc_warning (opt: OPT_Wunused_variable,
6143 "Unused variable %qs declared at %L",
6144 sym->name, &sym->declared_at);
6145 if (sym->backend_decl != NULL_TREE)
6146 suppress_warning (sym->backend_decl);
6147 }
6148 }
6149
6150 /* For variable length CHARACTER parameters, the PARM_DECL already
6151 references the length variable, so force gfc_get_symbol_decl
6152 even when not referenced. If optimize > 0, it will be optimized
6153 away anyway. But do this only after emitting -Wunused-parameter
6154 warning if requested. */
6155 if (sym->attr.dummy && !sym->attr.referenced
6156 && sym->ts.type == BT_CHARACTER
6157 && sym->ts.u.cl->backend_decl != NULL
6158 && VAR_P (sym->ts.u.cl->backend_decl))
6159 {
6160 sym->attr.referenced = 1;
6161 gfc_get_symbol_decl (sym);
6162 }
6163
6164 /* INTENT(out) dummy arguments and result variables with allocatable
6165 components are reset by default and need to be set referenced to
6166 generate the code for nullification and automatic lengths. */
6167 if (!sym->attr.referenced
6168 && sym->ts.type == BT_DERIVED
6169 && sym->ts.u.derived->attr.alloc_comp
6170 && !sym->attr.pointer
6171 && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT)
6172 ||
6173 (sym->attr.result && sym != sym->result)))
6174 {
6175 sym->attr.referenced = 1;
6176 gfc_get_symbol_decl (sym);
6177 }
6178
6179 /* Check for dependencies in the array specification and string
6180 length, adding the necessary declarations to the function. We
6181 mark the symbol now, as well as in traverse_ns, to prevent
6182 getting stuck in a circular dependency. */
6183 sym->mark = 1;
6184 }
6185 else if (sym->attr.flavor == FL_PARAMETER)
6186 {
6187 if (warn_unused_parameter
6188 && !sym->attr.referenced)
6189 {
6190 if (!sym->attr.use_assoc)
6191 gfc_warning (opt: OPT_Wunused_parameter,
6192 "Unused parameter %qs declared at %L", sym->name,
6193 &sym->declared_at);
6194 else if (sym->attr.use_only)
6195 gfc_warning (opt: OPT_Wunused_parameter,
6196 "Unused parameter %qs which has been explicitly "
6197 "imported at %L", sym->name, &sym->declared_at);
6198 }
6199
6200 if (sym->ns && sym->ns->construct_entities)
6201 {
6202 /* Construction of the intrinsic modules within a BLOCK
6203 construct, where ONLY and RENAMED entities are included,
6204 seems to be bogus. This is a workaround that can be removed
6205 if someone ever takes on the task to creating full-fledge
6206 modules. See PR 69455. */
6207 if (sym->attr.referenced
6208 && sym->from_intmod != INTMOD_ISO_C_BINDING
6209 && sym->from_intmod != INTMOD_ISO_FORTRAN_ENV)
6210 gfc_get_symbol_decl (sym);
6211 sym->mark = 1;
6212 }
6213 }
6214 else if (sym->attr.flavor == FL_PROCEDURE)
6215 {
6216 /* TODO: move to the appropriate place in resolve.cc. */
6217 if (warn_return_type > 0
6218 && sym->attr.function
6219 && sym->result
6220 && sym != sym->result
6221 && !sym->result->attr.referenced
6222 && !sym->attr.use_assoc
6223 && sym->attr.if_source != IFSRC_IFBODY)
6224 {
6225 gfc_warning (opt: OPT_Wreturn_type,
6226 "Return value %qs of function %qs declared at "
6227 "%L not set", sym->result->name, sym->name,
6228 &sym->result->declared_at);
6229
6230 /* Prevents "Unused variable" warning for RESULT variables. */
6231 sym->result->mark = 1;
6232 }
6233 }
6234
6235 if (sym->attr.dummy == 1)
6236 {
6237 /* The tree type for scalar character dummy arguments of BIND(C)
6238 procedures, if they are passed by value, should be unsigned char.
6239 The value attribute implies the dummy is a scalar. */
6240 if (sym->attr.value == 1 && sym->backend_decl != NULL
6241 && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
6242 && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
6243 {
6244 /* We used to modify the tree here. Now it is done earlier in
6245 the front-end, so we only check it here to avoid regressions. */
6246 gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
6247 gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
6248 gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
6249 gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
6250 }
6251
6252 /* Unused procedure passed as dummy argument. */
6253 if (sym->attr.flavor == FL_PROCEDURE)
6254 {
6255 if (!sym->attr.referenced && !sym->attr.artificial)
6256 {
6257 if (warn_unused_dummy_argument)
6258 gfc_warning (opt: OPT_Wunused_dummy_argument,
6259 "Unused dummy argument %qs at %L", sym->name,
6260 &sym->declared_at);
6261 }
6262
6263 /* Silence bogus "unused parameter" warnings from the
6264 middle end. */
6265 if (sym->backend_decl != NULL_TREE)
6266 suppress_warning (sym->backend_decl);
6267 }
6268 }
6269
6270 /* Make sure we convert the types of the derived types from iso_c_binding
6271 into (void *). */
6272 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
6273 && sym->ts.type == BT_DERIVED)
6274 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
6275}
6276
6277
6278static void
6279generate_local_nml_decl (gfc_symbol * sym)
6280{
6281 if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
6282 {
6283 tree decl = generate_namelist_decl (sym);
6284 pushdecl (decl);
6285 }
6286}
6287
6288
6289static void
6290generate_local_vars (gfc_namespace * ns)
6291{
6292 gfc_traverse_ns (ns, generate_local_decl);
6293 gfc_traverse_ns (ns, generate_local_nml_decl);
6294}
6295
6296
6297/* Generate a switch statement to jump to the correct entry point. Also
6298 creates the label decls for the entry points. */
6299
6300static tree
6301gfc_trans_entry_master_switch (gfc_entry_list * el)
6302{
6303 stmtblock_t block;
6304 tree label;
6305 tree tmp;
6306 tree val;
6307
6308 gfc_init_block (&block);
6309 for (; el; el = el->next)
6310 {
6311 /* Add the case label. */
6312 label = gfc_build_label_decl (NULL_TREE);
6313 val = build_int_cst (gfc_array_index_type, el->id);
6314 tmp = build_case_label (val, NULL_TREE, label);
6315 gfc_add_expr_to_block (&block, tmp);
6316
6317 /* And jump to the actual entry point. */
6318 label = gfc_build_label_decl (NULL_TREE);
6319 tmp = build1_v (GOTO_EXPR, label);
6320 gfc_add_expr_to_block (&block, tmp);
6321
6322 /* Save the label decl. */
6323 el->label = label;
6324 }
6325 tmp = gfc_finish_block (&block);
6326 /* The first argument selects the entry point. */
6327 val = DECL_ARGUMENTS (current_function_decl);
6328 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, val, tmp);
6329 return tmp;
6330}
6331
6332
6333/* Add code to string lengths of actual arguments passed to a function against
6334 the expected lengths of the dummy arguments. */
6335
6336static void
6337add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
6338{
6339 gfc_formal_arglist *formal;
6340
6341 for (formal = gfc_sym_get_dummy_args (sym); formal; formal = formal->next)
6342 if (formal->sym && formal->sym->ts.type == BT_CHARACTER
6343 && !formal->sym->ts.deferred)
6344 {
6345 enum tree_code comparison;
6346 tree cond;
6347 tree argname;
6348 gfc_symbol *fsym;
6349 gfc_charlen *cl;
6350 const char *message;
6351
6352 fsym = formal->sym;
6353 cl = fsym->ts.u.cl;
6354
6355 gcc_assert (cl);
6356 gcc_assert (cl->passed_length != NULL_TREE);
6357 gcc_assert (cl->backend_decl != NULL_TREE);
6358
6359 /* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the
6360 string lengths must match exactly. Otherwise, it is only required
6361 that the actual string length is *at least* the expected one.
6362 Sequence association allows for a mismatch of the string length
6363 if the actual argument is (part of) an array, but only if the
6364 dummy argument is an array. (See "Sequence association" in
6365 Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */
6366 if (fsym->attr.pointer || fsym->attr.allocatable
6367 || (fsym->as && (fsym->as->type == AS_ASSUMED_SHAPE
6368 || fsym->as->type == AS_ASSUMED_RANK)))
6369 {
6370 comparison = NE_EXPR;
6371 message = _("Actual string length does not match the declared one"
6372 " for dummy argument '%s' (%ld/%ld)");
6373 }
6374 else if (fsym->as && fsym->as->rank != 0)
6375 continue;
6376 else
6377 {
6378 comparison = LT_EXPR;
6379 message = _("Actual string length is shorter than the declared one"
6380 " for dummy argument '%s' (%ld/%ld)");
6381 }
6382
6383 /* Build the condition. For optional arguments, an actual length
6384 of 0 is also acceptable if the associated string is NULL, which
6385 means the argument was not passed. */
6386 cond = fold_build2_loc (input_location, comparison, logical_type_node,
6387 cl->passed_length, cl->backend_decl);
6388 if (fsym->attr.optional)
6389 {
6390 tree not_absent;
6391 tree not_0length;
6392 tree absent_failed;
6393
6394 not_0length = fold_build2_loc (input_location, NE_EXPR,
6395 logical_type_node,
6396 cl->passed_length,
6397 build_zero_cst
6398 (TREE_TYPE (cl->passed_length)));
6399 /* The symbol needs to be referenced for gfc_get_symbol_decl. */
6400 fsym->attr.referenced = 1;
6401 not_absent = gfc_conv_expr_present (fsym);
6402
6403 absent_failed = fold_build2_loc (input_location, TRUTH_OR_EXPR,
6404 logical_type_node, not_0length,
6405 not_absent);
6406
6407 cond = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6408 logical_type_node, cond, absent_failed);
6409 }
6410
6411 /* Build the runtime check. */
6412 argname = gfc_build_cstring_const (fsym->name);
6413 argname = gfc_build_addr_expr (pchar_type_node, argname);
6414 gfc_trans_runtime_check (true, false, cond, block, &fsym->declared_at,
6415 message, argname,
6416 fold_convert (long_integer_type_node,
6417 cl->passed_length),
6418 fold_convert (long_integer_type_node,
6419 cl->backend_decl));
6420 }
6421}
6422
6423
6424static void
6425create_main_function (tree fndecl)
6426{
6427 tree old_context;
6428 tree ftn_main;
6429 tree tmp, decl, result_decl, argc, argv, typelist, arglist;
6430 stmtblock_t body;
6431
6432 old_context = current_function_decl;
6433
6434 if (old_context)
6435 {
6436 push_function_context ();
6437 saved_parent_function_decls = saved_function_decls;
6438 saved_function_decls = NULL_TREE;
6439 }
6440
6441 /* main() function must be declared with global scope. */
6442 gcc_assert (current_function_decl == NULL_TREE);
6443
6444 /* Declare the function. */
6445 tmp = build_function_type_list (integer_type_node, integer_type_node,
6446 build_pointer_type (pchar_type_node),
6447 NULL_TREE);
6448 main_identifier_node = get_identifier ("main");
6449 ftn_main = build_decl (input_location, FUNCTION_DECL,
6450 main_identifier_node, tmp);
6451 DECL_EXTERNAL (ftn_main) = 0;
6452 TREE_PUBLIC (ftn_main) = 1;
6453 TREE_STATIC (ftn_main) = 1;
6454 DECL_ATTRIBUTES (ftn_main)
6455 = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
6456
6457 /* Setup the result declaration (for "return 0"). */
6458 result_decl = build_decl (input_location,
6459 RESULT_DECL, NULL_TREE, integer_type_node);
6460 DECL_ARTIFICIAL (result_decl) = 1;
6461 DECL_IGNORED_P (result_decl) = 1;
6462 DECL_CONTEXT (result_decl) = ftn_main;
6463 DECL_RESULT (ftn_main) = result_decl;
6464
6465 pushdecl (ftn_main);
6466
6467 /* Get the arguments. */
6468
6469 arglist = NULL_TREE;
6470 typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
6471
6472 tmp = TREE_VALUE (typelist);
6473 argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
6474 DECL_CONTEXT (argc) = ftn_main;
6475 DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
6476 TREE_READONLY (argc) = 1;
6477 gfc_finish_decl (decl: argc);
6478 arglist = chainon (arglist, argc);
6479
6480 typelist = TREE_CHAIN (typelist);
6481 tmp = TREE_VALUE (typelist);
6482 argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
6483 DECL_CONTEXT (argv) = ftn_main;
6484 DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
6485 TREE_READONLY (argv) = 1;
6486 DECL_BY_REFERENCE (argv) = 1;
6487 gfc_finish_decl (decl: argv);
6488 arglist = chainon (arglist, argv);
6489
6490 DECL_ARGUMENTS (ftn_main) = arglist;
6491 current_function_decl = ftn_main;
6492 announce_function (ftn_main);
6493
6494 rest_of_decl_compilation (ftn_main, 1, 0);
6495 make_decl_rtl (ftn_main);
6496 allocate_struct_function (ftn_main, false);
6497 pushlevel ();
6498
6499 gfc_init_block (&body);
6500
6501 /* Call some libgfortran initialization routines, call then MAIN__(). */
6502
6503 /* Call _gfortran_caf_init (*argc, ***argv). */
6504 if (flag_coarray == GFC_FCOARRAY_LIB)
6505 {
6506 tree pint_type, pppchar_type;
6507 pint_type = build_pointer_type (integer_type_node);
6508 pppchar_type
6509 = build_pointer_type (build_pointer_type (pchar_type_node));
6510
6511 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 2,
6512 gfc_build_addr_expr (pint_type, argc),
6513 gfc_build_addr_expr (pppchar_type, argv));
6514 gfc_add_expr_to_block (&body, tmp);
6515 }
6516
6517 /* Call _gfortran_set_args (argc, argv). */
6518 TREE_USED (argc) = 1;
6519 TREE_USED (argv) = 1;
6520 tmp = build_call_expr_loc (input_location,
6521 gfor_fndecl_set_args, 2, argc, argv);
6522 gfc_add_expr_to_block (&body, tmp);
6523
6524 /* Add a call to set_options to set up the runtime library Fortran
6525 language standard parameters. */
6526 {
6527 tree array_type, array, var;
6528 vec<constructor_elt, va_gc> *v = NULL;
6529 static const int noptions = 7;
6530
6531 /* Passing a new option to the library requires three modifications:
6532 + add it to the tree_cons list below
6533 + change the noptions variable above
6534 + modify the library (runtime/compile_options.c)! */
6535
6536 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6537 build_int_cst (integer_type_node,
6538 gfc_option.warn_std));
6539 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6540 build_int_cst (integer_type_node,
6541 gfc_option.allow_std));
6542 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6543 build_int_cst (integer_type_node, pedantic));
6544 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6545 build_int_cst (integer_type_node, flag_backtrace));
6546 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6547 build_int_cst (integer_type_node, flag_sign_zero));
6548 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6549 build_int_cst (integer_type_node,
6550 (gfc_option.rtcheck
6551 & GFC_RTCHECK_BOUNDS)));
6552 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6553 build_int_cst (integer_type_node,
6554 gfc_option.fpe_summary));
6555
6556 array_type = build_array_type_nelts (integer_type_node, noptions);
6557 array = build_constructor (array_type, v);
6558 TREE_CONSTANT (array) = 1;
6559 TREE_STATIC (array) = 1;
6560
6561 /* Create a static variable to hold the jump table. */
6562 var = build_decl (input_location, VAR_DECL,
6563 create_tmp_var_name ("options"), array_type);
6564 DECL_ARTIFICIAL (var) = 1;
6565 DECL_IGNORED_P (var) = 1;
6566 TREE_CONSTANT (var) = 1;
6567 TREE_STATIC (var) = 1;
6568 TREE_READONLY (var) = 1;
6569 DECL_INITIAL (var) = array;
6570 pushdecl (var);
6571 var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var);
6572
6573 tmp = build_call_expr_loc (input_location,
6574 gfor_fndecl_set_options, 2,
6575 build_int_cst (integer_type_node, noptions), var);
6576 gfc_add_expr_to_block (&body, tmp);
6577 }
6578
6579 /* If -ffpe-trap option was provided, add a call to set_fpe so that
6580 the library will raise a FPE when needed. */
6581 if (gfc_option.fpe != 0)
6582 {
6583 tmp = build_call_expr_loc (input_location,
6584 gfor_fndecl_set_fpe, 1,
6585 build_int_cst (integer_type_node,
6586 gfc_option.fpe));
6587 gfc_add_expr_to_block (&body, tmp);
6588 }
6589
6590 /* If this is the main program and an -fconvert option was provided,
6591 add a call to set_convert. */
6592
6593 if (flag_convert != GFC_FLAG_CONVERT_NATIVE)
6594 {
6595 tmp = build_call_expr_loc (input_location,
6596 gfor_fndecl_set_convert, 1,
6597 build_int_cst (integer_type_node, flag_convert));
6598 gfc_add_expr_to_block (&body, tmp);
6599 }
6600
6601 /* If this is the main program and an -frecord-marker option was provided,
6602 add a call to set_record_marker. */
6603
6604 if (flag_record_marker != 0)
6605 {
6606 tmp = build_call_expr_loc (input_location,
6607 gfor_fndecl_set_record_marker, 1,
6608 build_int_cst (integer_type_node,
6609 flag_record_marker));
6610 gfc_add_expr_to_block (&body, tmp);
6611 }
6612
6613 if (flag_max_subrecord_length != 0)
6614 {
6615 tmp = build_call_expr_loc (input_location,
6616 gfor_fndecl_set_max_subrecord_length, 1,
6617 build_int_cst (integer_type_node,
6618 flag_max_subrecord_length));
6619 gfc_add_expr_to_block (&body, tmp);
6620 }
6621
6622 /* Call MAIN__(). */
6623 tmp = build_call_expr_loc (input_location,
6624 fndecl, 0);
6625 gfc_add_expr_to_block (&body, tmp);
6626
6627 /* Mark MAIN__ as used. */
6628 TREE_USED (fndecl) = 1;
6629
6630 /* Coarray: Call _gfortran_caf_finalize(void). */
6631 if (flag_coarray == GFC_FCOARRAY_LIB)
6632 {
6633 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_finalize, 0);
6634 gfc_add_expr_to_block (&body, tmp);
6635 }
6636
6637 /* "return 0". */
6638 tmp = fold_build2_loc (input_location, MODIFY_EXPR, integer_type_node,
6639 DECL_RESULT (ftn_main),
6640 integer_zero_node);
6641 tmp = build1_v (RETURN_EXPR, tmp);
6642 gfc_add_expr_to_block (&body, tmp);
6643
6644
6645 DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body);
6646 decl = getdecls ();
6647
6648 /* Finish off this function and send it for code generation. */
6649 poplevel (1, 1);
6650 BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main;
6651
6652 DECL_SAVED_TREE (ftn_main)
6653 = fold_build3_loc (DECL_SOURCE_LOCATION (ftn_main), BIND_EXPR,
6654 void_type_node, decl, DECL_SAVED_TREE (ftn_main),
6655 DECL_INITIAL (ftn_main));
6656
6657 /* Output the GENERIC tree. */
6658 dump_function (phase: TDI_original, fn: ftn_main);
6659
6660 cgraph_node::finalize_function (ftn_main, true);
6661
6662 if (old_context)
6663 {
6664 pop_function_context ();
6665 saved_function_decls = saved_parent_function_decls;
6666 }
6667 current_function_decl = old_context;
6668}
6669
6670
6671/* Generate an appropriate return-statement for a procedure. */
6672
6673tree
6674gfc_generate_return (void)
6675{
6676 gfc_symbol* sym;
6677 tree result;
6678 tree fndecl;
6679
6680 sym = current_procedure_symbol;
6681 fndecl = sym->backend_decl;
6682
6683 if (TREE_TYPE (DECL_RESULT (fndecl)) == void_type_node)
6684 result = NULL_TREE;
6685 else
6686 {
6687 result = get_proc_result (sym);
6688
6689 /* Set the return value to the dummy result variable. The
6690 types may be different for scalar default REAL functions
6691 with -ff2c, therefore we have to convert. */
6692 if (result != NULL_TREE)
6693 {
6694 result = convert (TREE_TYPE (DECL_RESULT (fndecl)), result);
6695 result = fold_build2_loc (input_location, MODIFY_EXPR,
6696 TREE_TYPE (result), DECL_RESULT (fndecl),
6697 result);
6698 }
6699 else
6700 {
6701 /* If the function does not have a result variable, result is
6702 NULL_TREE, and a 'return' is generated without a variable.
6703 The following generates a 'return __result_XXX' where XXX is
6704 the function name. */
6705 if (sym == sym->result && sym->attr.function && !flag_f2c)
6706 {
6707 result = gfc_get_fake_result_decl (sym, parent_flag: 0);
6708 result = fold_build2_loc (input_location, MODIFY_EXPR,
6709 TREE_TYPE (result),
6710 DECL_RESULT (fndecl), result);
6711 }
6712 }
6713 }
6714
6715 return build1_v (RETURN_EXPR, result);
6716}
6717
6718
6719static void
6720is_from_ieee_module (gfc_symbol *sym)
6721{
6722 if (sym->from_intmod == INTMOD_IEEE_FEATURES
6723 || sym->from_intmod == INTMOD_IEEE_EXCEPTIONS
6724 || sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
6725 seen_ieee_symbol = 1;
6726}
6727
6728
6729static int
6730is_ieee_module_used (gfc_namespace *ns)
6731{
6732 seen_ieee_symbol = 0;
6733 gfc_traverse_ns (ns, is_from_ieee_module);
6734 return seen_ieee_symbol;
6735}
6736
6737
6738static gfc_omp_clauses *module_oacc_clauses;
6739
6740
6741static void
6742add_clause (gfc_symbol *sym, gfc_omp_map_op map_op)
6743{
6744 gfc_omp_namelist *n;
6745
6746 n = gfc_get_omp_namelist ();
6747 n->sym = sym;
6748 n->u.map.op = map_op;
6749
6750 if (!module_oacc_clauses)
6751 module_oacc_clauses = gfc_get_omp_clauses ();
6752
6753 if (module_oacc_clauses->lists[OMP_LIST_MAP])
6754 n->next = module_oacc_clauses->lists[OMP_LIST_MAP];
6755
6756 module_oacc_clauses->lists[OMP_LIST_MAP] = n;
6757}
6758
6759
6760static void
6761find_module_oacc_declare_clauses (gfc_symbol *sym)
6762{
6763 if (sym->attr.use_assoc)
6764 {
6765 gfc_omp_map_op map_op;
6766
6767 if (sym->attr.oacc_declare_create)
6768 map_op = OMP_MAP_FORCE_ALLOC;
6769
6770 if (sym->attr.oacc_declare_copyin)
6771 map_op = OMP_MAP_FORCE_TO;
6772
6773 if (sym->attr.oacc_declare_deviceptr)
6774 map_op = OMP_MAP_FORCE_DEVICEPTR;
6775
6776 if (sym->attr.oacc_declare_device_resident)
6777 map_op = OMP_MAP_DEVICE_RESIDENT;
6778
6779 if (sym->attr.oacc_declare_create
6780 || sym->attr.oacc_declare_copyin
6781 || sym->attr.oacc_declare_deviceptr
6782 || sym->attr.oacc_declare_device_resident)
6783 {
6784 sym->attr.referenced = 1;
6785 add_clause (sym, map_op);
6786 }
6787 }
6788}
6789
6790
6791void
6792finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
6793{
6794 gfc_code *code;
6795 gfc_oacc_declare *oc;
6796 locus where = gfc_current_locus;
6797 gfc_omp_clauses *omp_clauses = NULL;
6798 gfc_omp_namelist *n, *p;
6799
6800 module_oacc_clauses = NULL;
6801 gfc_traverse_ns (ns, find_module_oacc_declare_clauses);
6802
6803 if (module_oacc_clauses && sym->attr.flavor == FL_PROGRAM)
6804 {
6805 gfc_oacc_declare *new_oc;
6806
6807 new_oc = gfc_get_oacc_declare ();
6808 new_oc->next = ns->oacc_declare;
6809 new_oc->clauses = module_oacc_clauses;
6810
6811 ns->oacc_declare = new_oc;
6812 }
6813
6814 if (!ns->oacc_declare)
6815 return;
6816
6817 for (oc = ns->oacc_declare; oc; oc = oc->next)
6818 {
6819 if (oc->module_var)
6820 continue;
6821
6822 if (block)
6823 gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
6824 "in BLOCK construct", &oc->loc);
6825
6826
6827 if (oc->clauses && oc->clauses->lists[OMP_LIST_MAP])
6828 {
6829 if (omp_clauses == NULL)
6830 {
6831 omp_clauses = oc->clauses;
6832 continue;
6833 }
6834
6835 for (n = oc->clauses->lists[OMP_LIST_MAP]; n; p = n, n = n->next)
6836 ;
6837
6838 gcc_assert (p->next == NULL);
6839
6840 p->next = omp_clauses->lists[OMP_LIST_MAP];
6841 omp_clauses = oc->clauses;
6842 }
6843 }
6844
6845 if (!omp_clauses)
6846 return;
6847
6848 for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
6849 {
6850 switch (n->u.map.op)
6851 {
6852 case OMP_MAP_DEVICE_RESIDENT:
6853 n->u.map.op = OMP_MAP_FORCE_ALLOC;
6854 break;
6855
6856 default:
6857 break;
6858 }
6859 }
6860
6861 code = XCNEW (gfc_code);
6862 code->op = EXEC_OACC_DECLARE;
6863 code->loc = where;
6864
6865 code->ext.oacc_declare = gfc_get_oacc_declare ();
6866 code->ext.oacc_declare->clauses = omp_clauses;
6867
6868 code->block = XCNEW (gfc_code);
6869 code->block->op = EXEC_OACC_DECLARE;
6870 code->block->loc = where;
6871
6872 if (ns->code)
6873 code->block->next = ns->code;
6874
6875 ns->code = code;
6876
6877 return;
6878}
6879
6880static void
6881gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t *finally,
6882 tree cfi_desc, tree gfc_desc, gfc_symbol *sym)
6883{
6884 stmtblock_t block;
6885 gfc_init_block (&block);
6886 tree cfi = build_fold_indirect_ref_loc (input_location, cfi_desc);
6887 tree idx, etype, tmp, tmp2, size_var = NULL_TREE, rank = NULL_TREE;
6888 bool do_copy_inout = false;
6889
6890 /* When allocatable + intent out, free the cfi descriptor. */
6891 if (sym->attr.allocatable && sym->attr.intent == INTENT_OUT)
6892 {
6893 tmp = gfc_get_cfi_desc_base_addr (cfi);
6894 tree call = builtin_decl_explicit (fncode: BUILT_IN_FREE);
6895 call = build_call_expr_loc (input_location, call, 1, tmp);
6896 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
6897 gfc_add_modify (&block, tmp,
6898 fold_convert (TREE_TYPE (tmp), null_pointer_node));
6899 }
6900
6901 /* -fcheck=bound: Do version, rank, attribute, type and is-NULL checks. */
6902 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6903 {
6904 char *msg;
6905 tree tmp3;
6906 msg = xasprintf ("Unexpected version %%d (expected %d) in CFI descriptor "
6907 "passed to dummy argument %s", CFI_VERSION, sym->name);
6908 tmp2 = gfc_get_cfi_desc_version (cfi);
6909 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp2,
6910 build_int_cst (TREE_TYPE (tmp2), CFI_VERSION));
6911 gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6912 msg, tmp2);
6913 free (ptr: msg);
6914
6915 /* Rank check; however, for character(len=*), assumed/explicit-size arrays
6916 are permitted to differ in rank according to the Fortran rules. */
6917 if (sym->as && sym->as->type != AS_ASSUMED_SIZE
6918 && sym->as->type != AS_EXPLICIT)
6919 {
6920 if (sym->as->rank != -1)
6921 msg = xasprintf ("Invalid rank %%d (expected %d) in CFI descriptor "
6922 "passed to dummy argument %s", sym->as->rank,
6923 sym->name);
6924 else
6925 msg = xasprintf ("Invalid rank %%d (expected 0..%d) in CFI "
6926 "descriptor passed to dummy argument %s",
6927 CFI_MAX_RANK, sym->name);
6928
6929 tmp3 = tmp2 = tmp = gfc_get_cfi_desc_rank (cfi);
6930 if (sym->as->rank != -1)
6931 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6932 tmp, build_int_cst (signed_char_type_node,
6933 sym->as->rank));
6934 else
6935 {
6936 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
6937 tmp, build_zero_cst (TREE_TYPE (tmp)));
6938 tmp2 = fold_build2_loc (input_location, GT_EXPR,
6939 boolean_type_node, tmp2,
6940 build_int_cst (TREE_TYPE (tmp2),
6941 CFI_MAX_RANK));
6942 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6943 boolean_type_node, tmp, tmp2);
6944 }
6945 gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6946 msg, tmp3);
6947 free (ptr: msg);
6948 }
6949
6950 tmp3 = tmp = gfc_get_cfi_desc_attribute (cfi);
6951 if (sym->attr.allocatable || sym->attr.pointer)
6952 {
6953 int attr = (sym->attr.pointer ? CFI_attribute_pointer
6954 : CFI_attribute_allocatable);
6955 msg = xasprintf ("Invalid attribute %%d (expected %d) in CFI "
6956 "descriptor passed to dummy argument %s with %s "
6957 "attribute", attr, sym->name,
6958 sym->attr.pointer ? "pointer" : "allocatable");
6959 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6960 tmp, build_int_cst (TREE_TYPE (tmp), attr));
6961 }
6962 else
6963 {
6964 int amin = MIN (CFI_attribute_pointer,
6965 MIN (CFI_attribute_allocatable, CFI_attribute_other));
6966 int amax = MAX (CFI_attribute_pointer,
6967 MAX (CFI_attribute_allocatable, CFI_attribute_other));
6968 msg = xasprintf ("Invalid attribute %%d (expected %d..%d) in CFI "
6969 "descriptor passed to nonallocatable, nonpointer "
6970 "dummy argument %s", amin, amax, sym->name);
6971 tmp2 = tmp;
6972 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, tmp,
6973 build_int_cst (TREE_TYPE (tmp), amin));
6974 tmp2 = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp2,
6975 build_int_cst (TREE_TYPE (tmp2), amax));
6976 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6977 boolean_type_node, tmp, tmp2);
6978 gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6979 msg, tmp3);
6980 free (ptr: msg);
6981 msg = xasprintf ("Invalid unallocatated/unassociated CFI "
6982 "descriptor passed to nonallocatable, nonpointer "
6983 "dummy argument %s", sym->name);
6984 tmp3 = tmp = gfc_get_cfi_desc_base_addr (cfi),
6985 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6986 tmp, null_pointer_node);
6987 }
6988 gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6989 msg, tmp3);
6990 free (ptr: msg);
6991
6992 if (sym->ts.type != BT_ASSUMED)
6993 {
6994 int type = CFI_type_other;
6995 if (sym->ts.f90_type == BT_VOID)
6996 {
6997 type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
6998 ? CFI_type_cfunptr : CFI_type_cptr);
6999 }
7000 else
7001 switch (sym->ts.type)
7002 {
7003 case BT_INTEGER:
7004 case BT_LOGICAL:
7005 case BT_REAL:
7006 case BT_COMPLEX:
7007 type = CFI_type_from_type_kind (sym->ts.type, sym->ts.kind);
7008 break;
7009 case BT_CHARACTER:
7010 type = CFI_type_from_type_kind (CFI_type_Character,
7011 sym->ts.kind);
7012 break;
7013 case BT_DERIVED:
7014 type = CFI_type_struct;
7015 break;
7016 case BT_VOID:
7017 type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
7018 ? CFI_type_cfunptr : CFI_type_cptr);
7019 break;
7020 case BT_ASSUMED:
7021 case BT_CLASS:
7022 case BT_PROCEDURE:
7023 case BT_HOLLERITH:
7024 case BT_UNION:
7025 case BT_BOZ:
7026 case BT_UNKNOWN:
7027 gcc_unreachable ();
7028 }
7029 msg = xasprintf ("Unexpected type %%d (expected %d) in CFI descriptor"
7030 " passed to dummy argument %s", type, sym->name);
7031 tmp2 = tmp = gfc_get_cfi_desc_type (cfi);
7032 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7033 tmp, build_int_cst (TREE_TYPE (tmp), type));
7034 gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
7035 msg, tmp2);
7036 free (ptr: msg);
7037 }
7038 }
7039
7040 if (!sym->attr.referenced)
7041 goto done;
7042
7043 /* Set string length for len=* and len=:, otherwise, it is already set. */
7044 if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
7045 {
7046 tmp = fold_convert (gfc_array_index_type,
7047 gfc_get_cfi_desc_elem_len (cfi));
7048 if (sym->ts.kind != 1)
7049 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7050 gfc_array_index_type, tmp,
7051 build_int_cst (gfc_charlen_type_node,
7052 sym->ts.kind));
7053 gfc_add_modify (&block, sym->ts.u.cl->backend_decl, tmp);
7054 }
7055
7056 if (sym->ts.type == BT_CHARACTER
7057 && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
7058 {
7059 gfc_conv_string_length (sym->ts.u.cl, NULL, init);
7060 gfc_trans_vla_type_sizes (sym, body: init);
7061 }
7062
7063 /* gfc->data = cfi->base_addr - or for scalars: gfc = cfi->base_addr.
7064 assumed-size/explicit-size arrays end up here for character(len=*)
7065 only. */
7066 if (!sym->attr.dimension || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7067 {
7068 tmp = gfc_get_cfi_desc_base_addr (cfi);
7069 gfc_add_modify (&block, gfc_desc,
7070 fold_convert (TREE_TYPE (gfc_desc), tmp));
7071 if (!sym->attr.dimension)
7072 goto done;
7073 }
7074
7075 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7076 {
7077 /* gfc->dtype = ... (from declaration, not from cfi). */
7078 etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
7079 gfc_add_modify (&block, gfc_conv_descriptor_dtype (gfc_desc),
7080 gfc_get_dtype_rank_type (sym->as->rank, etype));
7081 /* gfc->data = cfi->base_addr. */
7082 gfc_conv_descriptor_data_set (&block, gfc_desc,
7083 gfc_get_cfi_desc_base_addr (cfi));
7084 }
7085
7086 if (sym->ts.type == BT_ASSUMED)
7087 {
7088 /* For type(*), take elem_len + dtype.type from the actual argument. */
7089 gfc_add_modify (&block, gfc_conv_descriptor_elem_len (gfc_desc),
7090 gfc_get_cfi_desc_elem_len (cfi));
7091 tree cond;
7092 tree ctype = gfc_get_cfi_desc_type (cfi);
7093 ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
7094 ctype, build_int_cst (TREE_TYPE (ctype),
7095 CFI_type_mask));
7096 tree type = gfc_conv_descriptor_type (gfc_desc);
7097
7098 /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN */
7099 /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
7100 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7101 build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
7102 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
7103 build_int_cst (TREE_TYPE (type), BT_VOID));
7104 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7105 type,
7106 build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
7107 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7108 tmp, tmp2);
7109 /* if (CFI_type_struct) BT_DERIVED else < tmp2 > */
7110 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7111 build_int_cst (TREE_TYPE (ctype),
7112 CFI_type_struct));
7113 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
7114 build_int_cst (TREE_TYPE (type), BT_DERIVED));
7115 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7116 tmp, tmp2);
7117 /* if (CFI_type_Character) BT_CHARACTER else < tmp2 > */
7118 /* Note: this is kind=1, CFI_type_ucs4_char is handled in the 'else if'
7119 before (see below, as generated bottom up). */
7120 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7121 build_int_cst (TREE_TYPE (ctype),
7122 CFI_type_Character));
7123 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
7124 build_int_cst (TREE_TYPE (type), BT_CHARACTER));
7125 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7126 tmp, tmp2);
7127 /* if (CFI_type_ucs4_char) BT_CHARACTER else < tmp2 > */
7128 /* Note: gfc->elem_len = cfi->elem_len/4. */
7129 /* However, assuming that CFI_type_ucs4_char cannot be recovered, leave
7130 gfc->elem_len == cfi->elem_len, which helps with operations which use
7131 sizeof() in Fortran and cfi->elem_len in C. */
7132 tmp = gfc_get_cfi_desc_type (cfi);
7133 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
7134 build_int_cst (TREE_TYPE (tmp),
7135 CFI_type_ucs4_char));
7136 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
7137 build_int_cst (TREE_TYPE (type), BT_CHARACTER));
7138 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7139 tmp, tmp2);
7140 /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else < tmp2 > */
7141 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7142 build_int_cst (TREE_TYPE (ctype),
7143 CFI_type_Complex));
7144 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
7145 build_int_cst (TREE_TYPE (type), BT_COMPLEX));
7146 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7147 tmp, tmp2);
7148 /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
7149 ctype else <tmp2> */
7150 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7151 build_int_cst (TREE_TYPE (ctype),
7152 CFI_type_Integer));
7153 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7154 build_int_cst (TREE_TYPE (ctype),
7155 CFI_type_Logical));
7156 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
7157 cond, tmp);
7158 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
7159 build_int_cst (TREE_TYPE (ctype),
7160 CFI_type_Real));
7161 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
7162 cond, tmp);
7163 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7164 type, fold_convert (TREE_TYPE (type), ctype));
7165 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
7166 tmp, tmp2);
7167 gfc_add_expr_to_block (&block, tmp2);
7168 }
7169
7170 if (sym->as->rank < 0)
7171 {
7172 /* Set gfc->dtype.rank, if assumed-rank. */
7173 rank = gfc_get_cfi_desc_rank (cfi);
7174 gfc_add_modify (&block, gfc_conv_descriptor_rank (gfc_desc), rank);
7175 }
7176 else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7177 /* In that case, the CFI rank and the declared rank can differ. */
7178 rank = gfc_get_cfi_desc_rank (cfi);
7179 else
7180 rank = build_int_cst (signed_char_type_node, sym->as->rank);
7181
7182 /* With bind(C), the standard requires that both Fortran callers and callees
7183 handle noncontiguous arrays passed to an dummy with 'contiguous' attribute
7184 and with character(len=*) + assumed-size/explicit-size arrays.
7185 cf. Fortran 2018, 18.3.6, paragraph 5 (and for the caller: para. 6). */
7186 if ((sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length
7187 && (sym->as->type == AS_ASSUMED_SIZE || sym->as->type == AS_EXPLICIT))
7188 || sym->attr.contiguous)
7189 {
7190 do_copy_inout = true;
7191 gcc_assert (!sym->attr.pointer);
7192 stmtblock_t block2;
7193 tree data;
7194 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7195 data = gfc_conv_descriptor_data_get (gfc_desc);
7196 else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
7197 data = gfc_build_addr_expr (NULL, gfc_desc);
7198 else
7199 data = gfc_desc;
7200
7201 /* Is copy-in/out needed? */
7202 /* do_copyin = rank != 0 && !assumed-size */
7203 tree cond_var = gfc_create_var (boolean_type_node, "do_copyin");
7204 tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7205 rank, build_zero_cst (TREE_TYPE (rank)));
7206 /* dim[rank-1].extent != -1 -> assumed size*/
7207 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (rank),
7208 rank, build_int_cst (TREE_TYPE (rank), 1));
7209 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7210 gfc_get_cfi_dim_extent (cfi, tmp),
7211 build_int_cst (gfc_array_index_type, -1));
7212 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
7213 boolean_type_node, cond, tmp);
7214 gfc_add_modify (&block, cond_var, cond);
7215 /* if (do_copyin) do_copyin = ... || ... || ... */
7216 gfc_init_block (&block2);
7217 /* dim[0].sm != elem_len */
7218 tmp = fold_convert (gfc_array_index_type,
7219 gfc_get_cfi_desc_elem_len (cfi));
7220 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7221 gfc_get_cfi_dim_sm (cfi, gfc_index_zero_node),
7222 tmp);
7223 gfc_add_modify (&block2, cond_var, cond);
7224
7225 /* for (i = 1; i < rank; ++i)
7226 cond &&= dim[i].sm != (dv->dim[i - 1].sm * dv->dim[i - 1].extent) */
7227 idx = gfc_create_var (TREE_TYPE (rank), "idx");
7228 stmtblock_t loop_body;
7229 gfc_init_block (&loop_body);
7230 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
7231 idx, build_int_cst (TREE_TYPE (idx), 1));
7232 tree tmp2 = gfc_get_cfi_dim_sm (cfi, tmp);
7233 tmp = gfc_get_cfi_dim_extent (cfi, tmp);
7234 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
7235 tmp2, tmp);
7236 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7237 gfc_get_cfi_dim_sm (cfi, idx), tmp);
7238 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
7239 cond_var, cond);
7240 gfc_add_modify (&loop_body, cond_var, cond);
7241 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
7242 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7243 gfc_finish_block (&loop_body));
7244 tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
7245 build_empty_stmt (input_location));
7246 gfc_add_expr_to_block (&block, tmp);
7247
7248 /* Copy-in body. */
7249 gfc_init_block (&block2);
7250 /* size = dim[0].extent; for (i = 1; i < rank; ++i) size *= dim[i].extent */
7251 size_var = gfc_create_var (size_type_node, "size");
7252 tmp = fold_convert (size_type_node,
7253 gfc_get_cfi_dim_extent (cfi, gfc_index_zero_node));
7254 gfc_add_modify (&block2, size_var, tmp);
7255
7256 gfc_init_block (&loop_body);
7257 tmp = fold_convert (size_type_node,
7258 gfc_get_cfi_dim_extent (cfi, idx));
7259 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7260 size_var, fold_convert (size_type_node, tmp));
7261 gfc_add_modify (&loop_body, size_var, tmp);
7262 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
7263 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7264 gfc_finish_block (&loop_body));
7265 /* data = malloc (size * elem_len) */
7266 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7267 size_var, gfc_get_cfi_desc_elem_len (cfi));
7268 tree call = builtin_decl_explicit (fncode: BUILT_IN_MALLOC);
7269 call = build_call_expr_loc (input_location, call, 1, tmp);
7270 gfc_add_modify (&block2, data, fold_convert (TREE_TYPE (data), call));
7271
7272 /* Copy the data:
7273 for (idx = 0; idx < size; ++idx)
7274 {
7275 shift = 0;
7276 tmpidx = idx
7277 for (dim = 0; dim < rank; ++dim)
7278 {
7279 shift += (tmpidx % extent[d]) * sm[d]
7280 tmpidx = tmpidx / extend[d]
7281 }
7282 memcpy (lhs + idx*elem_len, rhs + shift, elem_len)
7283 } .*/
7284 idx = gfc_create_var (size_type_node, "arrayidx");
7285 gfc_init_block (&loop_body);
7286 tree shift = gfc_create_var (size_type_node, "shift");
7287 tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
7288 gfc_add_modify (&loop_body, shift, build_zero_cst (TREE_TYPE (shift)));
7289 gfc_add_modify (&loop_body, tmpidx, idx);
7290 stmtblock_t inner_loop;
7291 gfc_init_block (&inner_loop);
7292 tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
7293 /* shift += (tmpidx % extent[d]) * sm[d] */
7294 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7295 size_type_node, tmpidx,
7296 fold_convert (size_type_node,
7297 gfc_get_cfi_dim_extent (cfi, dim)));
7298 tmp = fold_build2_loc (input_location, MULT_EXPR,
7299 size_type_node, tmp,
7300 fold_convert (size_type_node,
7301 gfc_get_cfi_dim_sm (cfi, dim)));
7302 gfc_add_modify (&inner_loop, shift,
7303 fold_build2_loc (input_location, PLUS_EXPR,
7304 size_type_node, shift, tmp));
7305 /* tmpidx = tmpidx / extend[d] */
7306 tmp = fold_convert (size_type_node, gfc_get_cfi_dim_extent (cfi, dim));
7307 gfc_add_modify (&inner_loop, tmpidx,
7308 fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7309 size_type_node, tmpidx, tmp));
7310 gfc_simple_for_loop (&loop_body, dim, build_zero_cst (TREE_TYPE (rank)),
7311 rank, LT_EXPR, build_int_cst (TREE_TYPE (dim), 1),
7312 gfc_finish_block (&inner_loop));
7313 /* Assign. */
7314 tmp = fold_convert (pchar_type_node, gfc_get_cfi_desc_base_addr (cfi));
7315 tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
7316 tree lhs;
7317 /* memcpy (lhs + idx*elem_len, rhs + shift, elem_len) */
7318 tree elem_len;
7319 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7320 elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
7321 else
7322 elem_len = gfc_get_cfi_desc_elem_len (cfi);
7323 lhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7324 elem_len, idx);
7325 lhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR, pchar_type_node,
7326 fold_convert (pchar_type_node, data), lhs);
7327 tmp = fold_convert (pvoid_type_node, tmp);
7328 lhs = fold_convert (pvoid_type_node, lhs);
7329 call = builtin_decl_explicit (fncode: BUILT_IN_MEMCPY);
7330 call = build_call_expr_loc (input_location, call, 3, lhs, tmp, elem_len);
7331 gfc_add_expr_to_block (&loop_body, fold_convert (void_type_node, call));
7332 gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7333 size_var, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7334 gfc_finish_block (&loop_body));
7335 /* if (cond) { block2 } */
7336 tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
7337 build_empty_stmt (input_location));
7338 gfc_add_expr_to_block (&block, tmp);
7339 }
7340
7341 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7342 {
7343 tree offset, type;
7344 type = TREE_TYPE (gfc_desc);
7345 gfc_trans_array_bounds (type, sym, &offset, &block);
7346 if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
7347 gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
7348 goto done;
7349 }
7350
7351 /* If cfi->data != NULL. */
7352 stmtblock_t block2;
7353 gfc_init_block (&block2);
7354
7355 /* if do_copy_inout: gfc->dspan = gfc->dtype.elem_len
7356 We use gfc instead of cfi on the RHS as this might be a constant. */
7357 tmp = fold_convert (gfc_array_index_type,
7358 gfc_conv_descriptor_elem_len (gfc_desc));
7359 if (!do_copy_inout)
7360 {
7361 /* gfc->dspan = ((cfi->dim[0].sm % gfc->elem_len)
7362 ? cfi->dim[0].sm : gfc->elem_len). */
7363 tree cond;
7364 tree tmp2 = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
7365 cond = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7366 gfc_array_index_type, tmp2, tmp);
7367 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7368 cond, gfc_index_zero_node);
7369 tmp = build3_loc (loc: input_location, code: COND_EXPR, type: gfc_array_index_type, arg0: cond,
7370 arg1: tmp2, arg2: tmp);
7371 }
7372 gfc_conv_descriptor_span_set (&block2, gfc_desc, tmp);
7373
7374 /* Calculate offset + set lbound, ubound and stride. */
7375 gfc_conv_descriptor_offset_set (&block2, gfc_desc, gfc_index_zero_node);
7376 if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
7377 for (int i = 0; i < sym->as->rank; ++i)
7378 {
7379 gfc_se se;
7380 gfc_init_se (&se, NULL );
7381 if (sym->as->lower[i])
7382 {
7383 gfc_conv_expr (se: &se, expr: sym->as->lower[i]);
7384 tmp = se.expr;
7385 }
7386 else
7387 tmp = gfc_index_one_node;
7388 gfc_add_block_to_block (&block2, &se.pre);
7389 gfc_conv_descriptor_lbound_set (&block2, gfc_desc, gfc_rank_cst[i],
7390 tmp);
7391 gfc_add_block_to_block (&block2, &se.post);
7392 }
7393
7394 /* Loop: for (i = 0; i < rank; ++i). */
7395 idx = gfc_create_var (TREE_TYPE (rank), "idx");
7396
7397 /* Loop body. */
7398 stmtblock_t loop_body;
7399 gfc_init_block (&loop_body);
7400 /* gfc->dim[i].lbound = ... */
7401 if (sym->attr.pointer || sym->attr.allocatable)
7402 {
7403 tmp = gfc_get_cfi_dim_lbound (cfi, idx);
7404 gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx, tmp);
7405 }
7406 else if (sym->as->rank < 0)
7407 gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx,
7408 gfc_index_one_node);
7409
7410 /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
7411 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7412 gfc_conv_descriptor_lbound_get (gfc_desc, idx),
7413 gfc_index_one_node);
7414 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7415 gfc_get_cfi_dim_extent (cfi, idx), tmp);
7416 gfc_conv_descriptor_ubound_set (&loop_body, gfc_desc, idx, tmp);
7417
7418 if (do_copy_inout)
7419 {
7420 /* gfc->dim[i].stride
7421 = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
7422 tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7423 idx, build_zero_cst (TREE_TYPE (idx)));
7424 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
7425 idx, build_int_cst (TREE_TYPE (idx), 1));
7426 tree tmp2 = gfc_get_cfi_dim_extent (cfi, tmp);
7427 tmp = gfc_conv_descriptor_stride_get (gfc_desc, tmp);
7428 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp2),
7429 tmp2, tmp);
7430 tmp = build3_loc (loc: input_location, code: COND_EXPR, type: gfc_array_index_type, arg0: cond,
7431 gfc_index_one_node, arg2: tmp);
7432 }
7433 else
7434 {
7435 /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
7436 tmp = gfc_get_cfi_dim_sm (cfi, idx);
7437 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7438 gfc_array_index_type, tmp,
7439 fold_convert (gfc_array_index_type,
7440 gfc_get_cfi_desc_elem_len (cfi)));
7441 }
7442 gfc_conv_descriptor_stride_set (&loop_body, gfc_desc, idx, tmp);
7443 /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
7444 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7445 gfc_conv_descriptor_stride_get (gfc_desc, idx),
7446 gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7447 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7448 gfc_conv_descriptor_offset_get (gfc_desc), tmp);
7449 gfc_conv_descriptor_offset_set (&loop_body, gfc_desc, tmp);
7450
7451 /* Generate loop. */
7452 gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7453 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7454 gfc_finish_block (&loop_body));
7455 if (sym->attr.allocatable || sym->attr.pointer)
7456 {
7457 tmp = gfc_get_cfi_desc_base_addr (cfi),
7458 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7459 tmp, null_pointer_node);
7460 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
7461 build_empty_stmt (input_location));
7462 gfc_add_expr_to_block (&block, tmp);
7463 }
7464 else
7465 gfc_add_block_to_block (&block, &block2);
7466
7467done:
7468 /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'. */
7469 if (sym->attr.optional)
7470 {
7471 tree present = fold_build2_loc (input_location, NE_EXPR,
7472 boolean_type_node, cfi_desc,
7473 null_pointer_node);
7474 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7475 sym->backend_decl,
7476 fold_convert (TREE_TYPE (sym->backend_decl),
7477 null_pointer_node));
7478 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block), tmp);
7479 gfc_add_expr_to_block (init, tmp);
7480 }
7481 else
7482 gfc_add_block_to_block (init, &block);
7483
7484 if (!sym->attr.referenced)
7485 return;
7486
7487 /* If pointer not changed, nothing to be done (except copy out) */
7488 if (!do_copy_inout && ((!sym->attr.pointer && !sym->attr.allocatable)
7489 || sym->attr.intent == INTENT_IN))
7490 return;
7491
7492 gfc_init_block (&block);
7493
7494 /* For bind(C), Fortran does not permit mixing 'pointer' with 'contiguous' (or
7495 len=*). Thus, when copy out is needed, the bounds ofthe descriptor remain
7496 unchanged. */
7497 if (do_copy_inout)
7498 {
7499 tree data, call;
7500 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7501 data = gfc_conv_descriptor_data_get (gfc_desc);
7502 else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
7503 data = gfc_build_addr_expr (NULL, gfc_desc);
7504 else
7505 data = gfc_desc;
7506 gfc_init_block (&block2);
7507 if (sym->attr.intent != INTENT_IN)
7508 {
7509 /* First, create the inner copy-out loop.
7510 for (idx = 0; idx < size; ++idx)
7511 {
7512 shift = 0;
7513 tmpidx = idx
7514 for (dim = 0; dim < rank; ++dim)
7515 {
7516 shift += (tmpidx % extent[d]) * sm[d]
7517 tmpidx = tmpidx / extend[d]
7518 }
7519 memcpy (lhs + shift, rhs + idx*elem_len, elem_len)
7520 } .*/
7521 stmtblock_t loop_body;
7522 idx = gfc_create_var (size_type_node, "arrayidx");
7523 gfc_init_block (&loop_body);
7524 tree shift = gfc_create_var (size_type_node, "shift");
7525 tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
7526 gfc_add_modify (&loop_body, shift,
7527 build_zero_cst (TREE_TYPE (shift)));
7528 gfc_add_modify (&loop_body, tmpidx, idx);
7529 stmtblock_t inner_loop;
7530 gfc_init_block (&inner_loop);
7531 tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
7532 /* shift += (tmpidx % extent[d]) * sm[d] */
7533 tmp = fold_convert (size_type_node,
7534 gfc_get_cfi_dim_extent (cfi, dim));
7535 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7536 size_type_node, tmpidx, tmp);
7537 tmp = fold_build2_loc (input_location, MULT_EXPR,
7538 size_type_node, tmp,
7539 fold_convert (size_type_node,
7540 gfc_get_cfi_dim_sm (cfi, dim)));
7541 gfc_add_modify (&inner_loop, shift,
7542 fold_build2_loc (input_location, PLUS_EXPR,
7543 size_type_node, shift, tmp));
7544 /* tmpidx = tmpidx / extend[d] */
7545 tmp = fold_convert (size_type_node,
7546 gfc_get_cfi_dim_extent (cfi, dim));
7547 gfc_add_modify (&inner_loop, tmpidx,
7548 fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7549 size_type_node, tmpidx, tmp));
7550 gfc_simple_for_loop (&loop_body, dim,
7551 build_zero_cst (TREE_TYPE (rank)), rank, LT_EXPR,
7552 build_int_cst (TREE_TYPE (dim), 1),
7553 gfc_finish_block (&inner_loop));
7554 /* Assign. */
7555 tree rhs;
7556 tmp = fold_convert (pchar_type_node,
7557 gfc_get_cfi_desc_base_addr (cfi));
7558 tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
7559 /* memcpy (lhs + shift, rhs + idx*elem_len, elem_len) */
7560 tree elem_len;
7561 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7562 elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
7563 else
7564 elem_len = gfc_get_cfi_desc_elem_len (cfi);
7565 rhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7566 elem_len, idx);
7567 rhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR,
7568 pchar_type_node,
7569 fold_convert (pchar_type_node, data), rhs);
7570 tmp = fold_convert (pvoid_type_node, tmp);
7571 rhs = fold_convert (pvoid_type_node, rhs);
7572 call = builtin_decl_explicit (fncode: BUILT_IN_MEMCPY);
7573 call = build_call_expr_loc (input_location, call, 3, tmp, rhs,
7574 elem_len);
7575 gfc_add_expr_to_block (&loop_body,
7576 fold_convert (void_type_node, call));
7577 gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7578 size_var, LT_EXPR,
7579 build_int_cst (TREE_TYPE (idx), 1),
7580 gfc_finish_block (&loop_body));
7581 }
7582 call = builtin_decl_explicit (fncode: BUILT_IN_FREE);
7583 call = build_call_expr_loc (input_location, call, 1, data);
7584 gfc_add_expr_to_block (&block2, call);
7585
7586 /* if (cfi->base_addr != gfc->data) { copy out; free(var) }; return */
7587 tree tmp2 = gfc_get_cfi_desc_base_addr (cfi);
7588 tmp2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7589 tmp2, fold_convert (TREE_TYPE (tmp2), data));
7590 tmp = build3_v (COND_EXPR, tmp2, gfc_finish_block (&block2),
7591 build_empty_stmt (input_location));
7592 gfc_add_expr_to_block (&block, tmp);
7593 goto done_finally;
7594 }
7595
7596 /* Update pointer + array data data on exit. */
7597 tmp = gfc_get_cfi_desc_base_addr (cfi);
7598 tmp2 = (!sym->attr.dimension
7599 ? gfc_desc : gfc_conv_descriptor_data_get (gfc_desc));
7600 gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
7601
7602 /* Set string length for len=:, only. */
7603 if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
7604 {
7605 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
7606 tmp = fold_convert (TREE_TYPE (tmp2), sym->ts.u.cl->backend_decl);
7607 if (sym->ts.kind != 1)
7608 tmp = fold_build2_loc (input_location, MULT_EXPR,
7609 TREE_TYPE (tmp2), tmp,
7610 build_int_cst (TREE_TYPE (tmp2), sym->ts.kind));
7611 gfc_add_modify (&block, tmp2, tmp);
7612 }
7613
7614 if (!sym->attr.dimension)
7615 goto done_finally;
7616
7617 gfc_init_block (&block2);
7618
7619 /* Loop: for (i = 0; i < rank; ++i). */
7620 idx = gfc_create_var (TREE_TYPE (rank), "idx");
7621
7622 /* Loop body. */
7623 gfc_init_block (&loop_body);
7624 /* cfi->dim[i].lower_bound = gfc->dim[i].lbound */
7625 gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx),
7626 gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7627 /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
7628 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7629 gfc_conv_descriptor_ubound_get (gfc_desc, idx),
7630 gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7631 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp,
7632 gfc_index_one_node);
7633 gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
7634 /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
7635 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7636 gfc_conv_descriptor_stride_get (gfc_desc, idx),
7637 gfc_conv_descriptor_span_get (gfc_desc));
7638 gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
7639
7640 /* Generate loop. */
7641 gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7642 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7643 gfc_finish_block (&loop_body));
7644 /* if (gfc->data != NULL) { block2 }. */
7645 tmp = gfc_get_cfi_desc_base_addr (cfi),
7646 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7647 tmp, null_pointer_node);
7648 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
7649 build_empty_stmt (input_location));
7650 gfc_add_expr_to_block (&block, tmp);
7651
7652done_finally:
7653 /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'. */
7654 if (sym->attr.optional)
7655 {
7656 tree present = fold_build2_loc (input_location, NE_EXPR,
7657 boolean_type_node, cfi_desc,
7658 null_pointer_node);
7659 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
7660 build_empty_stmt (input_location));
7661 gfc_add_expr_to_block (finally, tmp);
7662 }
7663 else
7664 gfc_add_block_to_block (finally, &block);
7665}
7666
7667/* Generate code for a function. */
7668
7669void
7670gfc_generate_function_code (gfc_namespace * ns)
7671{
7672 tree fndecl;
7673 tree old_context;
7674 tree decl;
7675 tree tmp;
7676 tree fpstate = NULL_TREE;
7677 stmtblock_t init, cleanup, outer_block;
7678 stmtblock_t body;
7679 gfc_wrapped_block try_block;
7680 tree recurcheckvar = NULL_TREE;
7681 gfc_symbol *sym;
7682 gfc_symbol *previous_procedure_symbol;
7683 int rank, ieee;
7684 bool is_recursive;
7685
7686 sym = ns->proc_name;
7687 previous_procedure_symbol = current_procedure_symbol;
7688 current_procedure_symbol = sym;
7689
7690 /* Initialize sym->tlink so that gfc_trans_deferred_vars does not get
7691 lost or worse. */
7692 sym->tlink = sym;
7693
7694 /* Create the declaration for functions with global scope. */
7695 if (!sym->backend_decl)
7696 gfc_create_function_decl (ns, global: false);
7697
7698 fndecl = sym->backend_decl;
7699 old_context = current_function_decl;
7700
7701 if (old_context)
7702 {
7703 push_function_context ();
7704 saved_parent_function_decls = saved_function_decls;
7705 saved_function_decls = NULL_TREE;
7706 }
7707
7708 trans_function_start (sym);
7709 gfc_current_locus = sym->declared_at;
7710
7711 gfc_init_block (&init);
7712 gfc_init_block (&cleanup);
7713 gfc_init_block (&outer_block);
7714
7715 if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER)
7716 {
7717 /* Copy length backend_decls to all entry point result
7718 symbols. */
7719 gfc_entry_list *el;
7720 tree backend_decl;
7721
7722 gfc_conv_const_charlen (ns->proc_name->ts.u.cl);
7723 backend_decl = ns->proc_name->result->ts.u.cl->backend_decl;
7724 for (el = ns->entries; el; el = el->next)
7725 el->sym->result->ts.u.cl->backend_decl = backend_decl;
7726 }
7727
7728 /* Translate COMMON blocks. */
7729 gfc_trans_common (ns);
7730
7731 /* Null the parent fake result declaration if this namespace is
7732 a module function or an external procedures. */
7733 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
7734 || ns->parent == NULL)
7735 parent_fake_result_decl = NULL_TREE;
7736
7737 /* For BIND(C):
7738 - deallocate intent-out allocatable dummy arguments.
7739 - Create GFC variable which will later be populated by convert_CFI_desc */
7740 if (sym->attr.is_bind_c)
7741 for (gfc_formal_arglist *formal = gfc_sym_get_dummy_args (sym);
7742 formal; formal = formal->next)
7743 {
7744 gfc_symbol *fsym = formal->sym;
7745 if (!is_CFI_desc (fsym, NULL))
7746 continue;
7747 if (!fsym->attr.referenced)
7748 {
7749 gfc_conv_cfi_to_gfc (init: &init, finally: &cleanup, cfi_desc: fsym->backend_decl,
7750 NULL_TREE, sym: fsym);
7751 continue;
7752 }
7753 /* Let's now create a local GFI descriptor. Afterwards:
7754 desc is the local descriptor,
7755 desc_p is a pointer to it
7756 and stored in sym->backend_decl
7757 GFC_DECL_SAVED_DESCRIPTOR (desc_p) contains the CFI descriptor
7758 -> PARM_DECL and before sym->backend_decl.
7759 For scalars, decl == decl_p is a pointer variable. */
7760 tree desc_p, desc;
7761 location_t loc = gfc_get_location (&sym->declared_at);
7762 if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length)
7763 fsym->ts.u.cl->backend_decl = gfc_create_var (gfc_array_index_type,
7764 fsym->name);
7765 else if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->backend_decl)
7766 {
7767 gfc_se se;
7768 gfc_init_se (&se, NULL );
7769 gfc_conv_expr (se: &se, expr: fsym->ts.u.cl->length);
7770 gfc_add_block_to_block (&init, &se.pre);
7771 fsym->ts.u.cl->backend_decl = se.expr;
7772 gcc_assert(se.post.head == NULL_TREE);
7773 }
7774 /* Nullify, otherwise gfc_sym_type will return the CFI type. */
7775 tree tmp = fsym->backend_decl;
7776 fsym->backend_decl = NULL;
7777 tree type = gfc_sym_type (fsym);
7778 gcc_assert (POINTER_TYPE_P (type));
7779 if (POINTER_TYPE_P (TREE_TYPE (type)))
7780 /* For instance, allocatable scalars. */
7781 type = TREE_TYPE (type);
7782 if (TREE_CODE (type) == REFERENCE_TYPE)
7783 type = build_pointer_type (TREE_TYPE (type));
7784 desc_p = build_decl (loc, VAR_DECL, get_identifier (fsym->name), type);
7785 if (!fsym->attr.dimension)
7786 desc = desc_p;
7787 else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (desc_p))))
7788 {
7789 /* Character(len=*) explicit-size/assumed-size array. */
7790 desc = desc_p;
7791 gfc_build_qualified_array (decl: desc, sym: fsym);
7792 }
7793 else
7794 {
7795 tree size = size_in_bytes (TREE_TYPE (TREE_TYPE (desc_p)));
7796 tree call = builtin_decl_explicit (fncode: BUILT_IN_ALLOCA);
7797 call = build_call_expr_loc (input_location, call, 1, size);
7798 gfc_add_modify (&outer_block, desc_p,
7799 fold_convert (TREE_TYPE(desc_p), call));
7800 desc = build_fold_indirect_ref_loc (input_location, desc_p);
7801 }
7802 pushdecl (desc_p);
7803 if (fsym->attr.optional)
7804 {
7805 gfc_allocate_lang_decl (decl: desc_p);
7806 GFC_DECL_OPTIONAL_ARGUMENT (desc_p) = 1;
7807 }
7808 fsym->backend_decl = desc_p;
7809 gfc_conv_cfi_to_gfc (init: &init, finally: &cleanup, cfi_desc: tmp, gfc_desc: desc, sym: fsym);
7810 }
7811
7812 gfc_generate_contained_functions (parent: ns);
7813
7814 has_coarray_vars = false;
7815 generate_local_vars (ns);
7816
7817 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
7818 generate_coarray_init (ns);
7819
7820 /* Keep the parent fake result declaration in module functions
7821 or external procedures. */
7822 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
7823 || ns->parent == NULL)
7824 current_fake_result_decl = parent_fake_result_decl;
7825 else
7826 current_fake_result_decl = NULL_TREE;
7827
7828 is_recursive = sym->attr.recursive
7829 || (sym->attr.entry_master
7830 && sym->ns->entries->sym->attr.recursive);
7831 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
7832 && !is_recursive && !flag_recursive && !sym->attr.artificial)
7833 {
7834 char * msg;
7835
7836 msg = xasprintf ("Recursive call to nonrecursive procedure '%s'",
7837 sym->name);
7838 recurcheckvar = gfc_create_var (logical_type_node, "is_recursive");
7839 TREE_STATIC (recurcheckvar) = 1;
7840 DECL_INITIAL (recurcheckvar) = logical_false_node;
7841 gfc_add_expr_to_block (&init, recurcheckvar);
7842 gfc_trans_runtime_check (true, false, recurcheckvar, &init,
7843 &sym->declared_at, msg);
7844 gfc_add_modify (&init, recurcheckvar, logical_true_node);
7845 free (ptr: msg);
7846 }
7847
7848 /* Check if an IEEE module is used in the procedure. If so, save
7849 the floating point state. */
7850 ieee = is_ieee_module_used (ns);
7851 if (ieee)
7852 fpstate = gfc_save_fp_state (&init);
7853
7854 /* Now generate the code for the body of this function. */
7855 gfc_init_block (&body);
7856
7857 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
7858 && sym->attr.subroutine)
7859 {
7860 tree alternate_return;
7861 alternate_return = gfc_get_fake_result_decl (sym, parent_flag: 0);
7862 gfc_add_modify (&body, alternate_return, integer_zero_node);
7863 }
7864
7865 if (ns->entries)
7866 {
7867 /* Jump to the correct entry point. */
7868 tmp = gfc_trans_entry_master_switch (el: ns->entries);
7869 gfc_add_expr_to_block (&body, tmp);
7870 }
7871
7872 /* If bounds-checking is enabled, generate code to check passed in actual
7873 arguments against the expected dummy argument attributes (e.g. string
7874 lengths). */
7875 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c)
7876 add_argument_checking (block: &body, sym);
7877
7878 finish_oacc_declare (ns, sym, block: false);
7879
7880 tmp = gfc_trans_code (ns->code);
7881 gfc_add_expr_to_block (&body, tmp);
7882
7883 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
7884 || (sym->result && sym->result != sym
7885 && sym->result->ts.type == BT_DERIVED
7886 && sym->result->ts.u.derived->attr.alloc_comp))
7887 {
7888 bool artificial_result_decl = false;
7889 tree result = get_proc_result (sym);
7890 gfc_symbol *rsym = sym == sym->result ? sym : sym->result;
7891
7892 /* Make sure that a function returning an object with
7893 alloc/pointer_components always has a result, where at least
7894 the allocatable/pointer components are set to zero. */
7895 if (result == NULL_TREE && sym->attr.function
7896 && ((sym->result->ts.type == BT_DERIVED
7897 && (sym->attr.allocatable
7898 || sym->attr.pointer
7899 || sym->result->ts.u.derived->attr.alloc_comp
7900 || sym->result->ts.u.derived->attr.pointer_comp))
7901 || (sym->result->ts.type == BT_CLASS
7902 && (CLASS_DATA (sym)->attr.allocatable
7903 || CLASS_DATA (sym)->attr.class_pointer
7904 || CLASS_DATA (sym->result)->attr.alloc_comp
7905 || CLASS_DATA (sym->result)->attr.pointer_comp))))
7906 {
7907 artificial_result_decl = true;
7908 result = gfc_get_fake_result_decl (sym, parent_flag: 0);
7909 }
7910
7911 if (result != NULL_TREE && sym->attr.function && !sym->attr.pointer)
7912 {
7913 if (sym->attr.allocatable && sym->attr.dimension == 0
7914 && sym->result == sym)
7915 gfc_add_modify (&init, result, fold_convert (TREE_TYPE (result),
7916 null_pointer_node));
7917 else if (sym->ts.type == BT_CLASS
7918 && CLASS_DATA (sym)->attr.allocatable
7919 && CLASS_DATA (sym)->attr.dimension == 0
7920 && sym->result == sym)
7921 {
7922 tmp = CLASS_DATA (sym)->backend_decl;
7923 tmp = fold_build3_loc (input_location, COMPONENT_REF,
7924 TREE_TYPE (tmp), result, tmp, NULL_TREE);
7925 gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
7926 null_pointer_node));
7927 }
7928 else if (sym->ts.type == BT_DERIVED
7929 && !sym->attr.allocatable)
7930 {
7931 gfc_expr *init_exp;
7932 /* Arrays are not initialized using the default initializer of
7933 their elements. Therefore only check if a default
7934 initializer is available when the result is scalar. */
7935 init_exp = rsym->as ? NULL
7936 : gfc_generate_initializer (&rsym->ts, true);
7937 if (init_exp)
7938 {
7939 tmp = gfc_trans_structure_assign (result, init_exp, 0);
7940 gfc_free_expr (init_exp);
7941 gfc_add_expr_to_block (&init, tmp);
7942 }
7943 else if (rsym->ts.u.derived->attr.alloc_comp)
7944 {
7945 rank = rsym->as ? rsym->as->rank : 0;
7946 tmp = gfc_nullify_alloc_comp (rsym->ts.u.derived, result,
7947 rank);
7948 gfc_prepend_expr_to_block (&body, tmp);
7949 }
7950 }
7951 }
7952
7953 if (result == NULL_TREE || artificial_result_decl)
7954 {
7955 /* TODO: move to the appropriate place in resolve.cc. */
7956 if (warn_return_type > 0 && sym == sym->result)
7957 gfc_warning (opt: OPT_Wreturn_type,
7958 "Return value of function %qs at %L not set",
7959 sym->name, &sym->declared_at);
7960 if (warn_return_type > 0)
7961 suppress_warning (sym->backend_decl);
7962 }
7963 if (result != NULL_TREE)
7964 gfc_add_expr_to_block (&body, gfc_generate_return ());
7965 }
7966
7967 /* Reset recursion-check variable. */
7968 if (recurcheckvar != NULL_TREE)
7969 {
7970 gfc_add_modify (&cleanup, recurcheckvar, logical_false_node);
7971 recurcheckvar = NULL;
7972 }
7973
7974 /* If IEEE modules are loaded, restore the floating-point state. */
7975 if (ieee)
7976 gfc_restore_fp_state (&cleanup, fpstate);
7977
7978 /* Finish the function body and add init and cleanup code. */
7979 tmp = gfc_finish_block (&body);
7980 /* Add code to create and cleanup arrays. */
7981 gfc_start_wrapped_block (block: &try_block, code: tmp);
7982 gfc_trans_deferred_vars (proc_sym: sym, block: &try_block);
7983 gfc_add_init_cleanup (block: &try_block, init: gfc_finish_block (&init),
7984 cleanup: gfc_finish_block (&cleanup));
7985
7986 /* Add all the decls we created during processing. */
7987 decl = nreverse (saved_function_decls);
7988 while (decl)
7989 {
7990 tree next;
7991
7992 next = DECL_CHAIN (decl);
7993 DECL_CHAIN (decl) = NULL_TREE;
7994 pushdecl (decl);
7995 decl = next;
7996 }
7997 saved_function_decls = NULL_TREE;
7998
7999 gfc_add_expr_to_block (&outer_block, gfc_finish_wrapped_block (block: &try_block));
8000 DECL_SAVED_TREE (fndecl) = gfc_finish_block (&outer_block);
8001 decl = getdecls ();
8002
8003 /* Finish off this function and send it for code generation. */
8004 poplevel (1, 1);
8005 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
8006
8007 DECL_SAVED_TREE (fndecl)
8008 = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
8009 decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
8010
8011 /* Output the GENERIC tree. */
8012 dump_function (phase: TDI_original, fn: fndecl);
8013
8014 /* Store the end of the function, so that we get good line number
8015 info for the epilogue. */
8016 cfun->function_end_locus = input_location;
8017
8018 /* We're leaving the context of this function, so zap cfun.
8019 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
8020 tree_rest_of_compilation. */
8021 set_cfun (NULL);
8022
8023 if (old_context)
8024 {
8025 pop_function_context ();
8026 saved_function_decls = saved_parent_function_decls;
8027 }
8028 current_function_decl = old_context;
8029
8030 if (decl_function_context (fndecl))
8031 {
8032 /* Register this function with cgraph just far enough to get it
8033 added to our parent's nested function list.
8034 If there are static coarrays in this function, the nested _caf_init
8035 function has already called cgraph_create_node, which also created
8036 the cgraph node for this function. */
8037 if (!has_coarray_vars || flag_coarray != GFC_FCOARRAY_LIB)
8038 (void) cgraph_node::get_create (fndecl);
8039 }
8040 else
8041 cgraph_node::finalize_function (fndecl, true);
8042
8043 gfc_trans_use_stmts (ns);
8044 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
8045
8046 if (sym->attr.is_main_program)
8047 create_main_function (fndecl);
8048
8049 current_procedure_symbol = previous_procedure_symbol;
8050}
8051
8052
8053void
8054gfc_generate_constructors (void)
8055{
8056 gcc_assert (gfc_static_ctors == NULL_TREE);
8057#if 0
8058 tree fnname;
8059 tree type;
8060 tree fndecl;
8061 tree decl;
8062 tree tmp;
8063
8064 if (gfc_static_ctors == NULL_TREE)
8065 return;
8066
8067 fnname = get_file_function_name ("I");
8068 type = build_function_type_list (void_type_node, NULL_TREE);
8069
8070 fndecl = build_decl (input_location,
8071 FUNCTION_DECL, fnname, type);
8072 TREE_PUBLIC (fndecl) = 1;
8073
8074 decl = build_decl (input_location,
8075 RESULT_DECL, NULL_TREE, void_type_node);
8076 DECL_ARTIFICIAL (decl) = 1;
8077 DECL_IGNORED_P (decl) = 1;
8078 DECL_CONTEXT (decl) = fndecl;
8079 DECL_RESULT (fndecl) = decl;
8080
8081 pushdecl (fndecl);
8082
8083 current_function_decl = fndecl;
8084
8085 rest_of_decl_compilation (fndecl, 1, 0);
8086
8087 make_decl_rtl (fndecl);
8088
8089 allocate_struct_function (fndecl, false);
8090
8091 pushlevel ();
8092
8093 for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
8094 {
8095 tmp = build_call_expr_loc (input_location,
8096 TREE_VALUE (gfc_static_ctors), 0);
8097 DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
8098 }
8099
8100 decl = getdecls ();
8101 poplevel (1, 1);
8102
8103 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
8104 DECL_SAVED_TREE (fndecl)
8105 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
8106 DECL_INITIAL (fndecl));
8107
8108 free_after_parsing (cfun);
8109 free_after_compilation (cfun);
8110
8111 tree_rest_of_compilation (fndecl);
8112
8113 current_function_decl = NULL_TREE;
8114#endif
8115}
8116
8117/* Translates a BLOCK DATA program unit. This means emitting the
8118 commons contained therein plus their initializations. We also emit
8119 a globally visible symbol to make sure that each BLOCK DATA program
8120 unit remains unique. */
8121
8122void
8123gfc_generate_block_data (gfc_namespace * ns)
8124{
8125 tree decl;
8126 tree id;
8127
8128 /* Tell the backend the source location of the block data. */
8129 if (ns->proc_name)
8130 gfc_set_backend_locus (&ns->proc_name->declared_at);
8131 else
8132 gfc_set_backend_locus (&gfc_current_locus);
8133
8134 /* Process the DATA statements. */
8135 gfc_trans_common (ns);
8136
8137 /* Create a global symbol with the mane of the block data. This is to
8138 generate linker errors if the same name is used twice. It is never
8139 really used. */
8140 if (ns->proc_name)
8141 id = gfc_sym_mangled_function_id (sym: ns->proc_name);
8142 else
8143 id = get_identifier ("__BLOCK_DATA__");
8144
8145 decl = build_decl (input_location,
8146 VAR_DECL, id, gfc_array_index_type);
8147 TREE_PUBLIC (decl) = 1;
8148 TREE_STATIC (decl) = 1;
8149 DECL_IGNORED_P (decl) = 1;
8150
8151 pushdecl (decl);
8152 rest_of_decl_compilation (decl, 1, 0);
8153}
8154
8155
8156/* Process the local variables of a BLOCK construct. */
8157
8158void
8159gfc_process_block_locals (gfc_namespace* ns)
8160{
8161 tree decl;
8162
8163 saved_local_decls = NULL_TREE;
8164 has_coarray_vars = false;
8165
8166 generate_local_vars (ns);
8167
8168 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
8169 generate_coarray_init (ns);
8170
8171 decl = nreverse (saved_local_decls);
8172 while (decl)
8173 {
8174 tree next;
8175
8176 next = DECL_CHAIN (decl);
8177 DECL_CHAIN (decl) = NULL_TREE;
8178 pushdecl (decl);
8179 decl = next;
8180 }
8181 saved_local_decls = NULL_TREE;
8182}
8183
8184
8185#include "gt-fortran-trans-decl.h"
8186

source code of gcc/fortran/trans-decl.cc