LCOV - code coverage report
Current view: top level - gcc/fortran - trans-decl.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.2 % 4096 3941
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 96 96
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.