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-03-28 14:25:54 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       286890 : gfc_add_decl_to_function (tree decl)
     266              : {
     267       286890 :   gcc_assert (decl);
     268       286890 :   TREE_USED (decl) = 1;
     269       286890 :   DECL_CONTEXT (decl) = current_function_decl;
     270       286890 :   DECL_CHAIN (decl) = saved_function_decls;
     271       286890 :   saved_function_decls = decl;
     272       286890 : }
     273              : 
     274              : static void
     275        12962 : add_decl_as_local (tree decl)
     276              : {
     277        12962 :   gcc_assert (decl);
     278        12962 :   TREE_USED (decl) = 1;
     279        12962 :   DECL_CONTEXT (decl) = current_function_decl;
     280        12962 :   DECL_CHAIN (decl) = saved_local_decls;
     281        12962 :   saved_local_decls = decl;
     282        12962 : }
     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       618625 : gfc_build_label_decl (tree label_id)
     291              : {
     292              :   /* 2^32 temporaries should be enough.  */
     293       618625 :   static unsigned int tmp_num = 1;
     294       618625 :   tree label_decl;
     295       618625 :   char *label_name;
     296              : 
     297       618625 :   if (label_id == NULL_TREE)
     298              :     {
     299              :       /* Build an internal label name.  */
     300       615105 :       ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++);
     301       615105 :       label_id = get_identifier (label_name);
     302              :     }
     303              :   else
     304       618625 :     label_name = NULL;
     305              : 
     306              :   /* Build the LABEL_DECL node. Labels have no type.  */
     307       618625 :   label_decl = build_decl (input_location,
     308              :                            LABEL_DECL, label_id, void_type_node);
     309       618625 :   DECL_CONTEXT (label_decl) = current_function_decl;
     310       618625 :   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       618625 :   TREE_USED (label_decl) = 1;
     317              : 
     318       618625 :   DECL_ARTIFICIAL (label_decl) = 1;
     319       618625 :   return label_decl;
     320              : }
     321              : 
     322              : 
     323              : /* Set the backend source location of a decl.  */
     324              : 
     325              : void
     326       181664 : gfc_set_decl_location (tree decl, locus * loc)
     327              : {
     328       181664 :   DECL_SOURCE_LOCATION (decl) = gfc_get_location (loc);
     329       181664 : }
     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       413791 : sym_identifier (gfc_symbol *sym)
     373              : {
     374       413791 :   if (sym->attr.is_main_program && strcmp (sym->name, "main") == 0)
     375              :     return "MAIN__";
     376              :   else
     377       409466 :     return sym->name;
     378              : }
     379              : 
     380              : /* Convert a gfc_symbol to an identifier of the same name.  */
     381              : 
     382              : static tree
     383       413791 : gfc_sym_identifier (gfc_symbol * sym)
     384              : {
     385       413791 :   return get_identifier (sym_identifier (sym));
     386              : }
     387              : 
     388              : /* Construct mangled name from symbol name.   */
     389              : 
     390              : static const char *
     391        19600 : mangled_identifier (gfc_symbol *sym)
     392              : {
     393        19600 :   gfc_symbol *proc = sym->ns->proc_name;
     394        19600 :   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        19600 :   if (sym->attr.is_bind_c == 1 && sym->binding_label)
     399              :     return sym->binding_label;
     400              : 
     401        19475 :   if (!sym->fn_result_spec
     402           57 :       || (sym->module && !(proc && proc->attr.flavor == FL_PROCEDURE)))
     403              :     {
     404        19426 :       if (sym->module == NULL)
     405            0 :         return sym_identifier (sym);
     406              :       else
     407        19426 :         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        19451 : gfc_sym_mangled_identifier (gfc_symbol * sym)
     431              : {
     432        19451 :   tree result;
     433        19451 :   gfc_gsymbol *gsym;
     434        19451 :   const char *name;
     435              : 
     436        19451 :   name = mangled_identifier (sym);
     437        19451 :   result = get_identifier (name);
     438              : 
     439        19451 :   gsym = gfc_find_gsymbol (gfc_gsym_root, name);
     440        19451 :   if (gsym == NULL)
     441              :     {
     442        19275 :       gsym = gfc_get_gsymbol (name, false);
     443        19275 :       gsym->ns = sym->ns;
     444        19275 :       gsym->sym_name = sym->name;
     445              :     }
     446              : 
     447        19451 :   return result;
     448              : }
     449              : 
     450              : /* Construct mangled function name from symbol name.  */
     451              : 
     452              : static tree
     453        80656 : gfc_sym_mangled_function_id (gfc_symbol * sym)
     454              : {
     455        80656 :   int has_underscore;
     456        80656 :   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        80656 :   if ((sym->attr.is_bind_c == 1 || sym->attr.is_iso_c == 1) &&
     462         3407 :       sym->binding_label)
     463              :     /* use the binding label rather than the mangled name */
     464         3397 :     return get_identifier (sym->binding_label);
     465              : 
     466        77259 :   if ((sym->module == NULL || sym->attr.proc == PROC_EXTERNAL
     467        26278 :       || (sym->module != NULL && (sym->attr.external
     468        25223 :             || sym->attr.if_source == IFSRC_IFBODY)))
     469        52036 :       && !sym->attr.module_procedure)
     470              :     {
     471              :       /* Main program is mangled into MAIN__.  */
     472        51643 :       if (sym->attr.is_main_program)
     473        26085 :         return get_identifier ("MAIN__");
     474              : 
     475              :       /* Intrinsic procedures are never mangled.  */
     476        25558 :       if (sym->attr.proc == PROC_INTRINSIC)
     477        10961 :         return get_identifier (sym->name);
     478              : 
     479        14597 :       if (flag_underscoring)
     480              :         {
     481        13782 :           has_underscore = strchr (sym->name, '_') != 0;
     482        13782 :           if (flag_second_underscore && has_underscore)
     483          201 :             snprintf (name, sizeof name, "%s__", sym->name);
     484              :           else
     485        13581 :             snprintf (name, sizeof name, "%s_", sym->name);
     486        13782 :           return get_identifier (name);
     487              :         }
     488              :       else
     489          815 :         return get_identifier (sym->name);
     490              :     }
     491              :   else
     492              :     {
     493        25616 :       snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
     494        25616 :       return get_identifier (name);
     495              :     }
     496              : }
     497              : 
     498              : 
     499              : void
     500       102384 : gfc_set_decl_assembler_name (tree decl, tree name)
     501              : {
     502       102384 :   tree target_mangled = targetm.mangle_decl_assembler_name (decl, name);
     503       102384 :   SET_DECL_ASSEMBLER_NAME (decl, target_mangled);
     504       102384 : }
     505              : 
     506              : 
     507              : /* Returns true if a variable of specified size should go on the stack.  */
     508              : 
     509              : bool
     510       170918 : gfc_can_put_var_on_stack (tree size)
     511              : {
     512       170918 :   unsigned HOST_WIDE_INT low;
     513              : 
     514       170918 :   if (!INTEGER_CST_P (size))
     515              :     return 0;
     516              : 
     517       163424 :   if (flag_max_stack_var_size < 0)
     518              :     return 1;
     519              : 
     520       135723 :   if (!tree_fits_uhwi_p (size))
     521              :     return 0;
     522              : 
     523       135723 :   low = TREE_INT_CST_LOW (size);
     524       135723 :   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       173235 : gfc_finish_decl (tree decl)
     576              : {
     577       173235 :   gcc_assert (TREE_CODE (decl) == PARM_DECL
     578              :               || DECL_INITIAL (decl) == NULL_TREE);
     579              : 
     580       173235 :   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       417427 : gfc_finish_decl_attrs (tree decl, symbol_attribute *attr)
     611              : {
     612       417427 :   if (!attr->dimension && !attr->codimension)
     613              :     {
     614              :       /* Handle scalar allocatable variables.  */
     615       331030 :       if (attr->allocatable)
     616              :         {
     617         6786 :           gfc_allocate_lang_decl (decl);
     618         6786 :           GFC_DECL_SCALAR_ALLOCATABLE (decl) = 1;
     619              :         }
     620              :       /* Handle scalar pointer variables.  */
     621       331030 :       if (attr->pointer)
     622              :         {
     623        41323 :           gfc_allocate_lang_decl (decl);
     624        41323 :           GFC_DECL_SCALAR_POINTER (decl) = 1;
     625              :         }
     626       331030 :       if (attr->target)
     627              :         {
     628        25125 :           gfc_allocate_lang_decl (decl);
     629        25125 :           GFC_DECL_SCALAR_TARGET (decl) = 1;
     630              :         }
     631              :     }
     632       417427 : }
     633              : 
     634              : 
     635              : /* Apply symbol attributes to a variable, and add it to the function scope.  */
     636              : 
     637              : static void
     638       183684 : gfc_finish_var_decl (tree decl, gfc_symbol * sym)
     639              : {
     640       183684 :   tree new_type;
     641              : 
     642              :   /* Set DECL_VALUE_EXPR for Cray Pointees.  */
     643       183684 :   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       183684 :   if (sym->attr.target)
     651        27441 :     TREE_ADDRESSABLE (decl) = 1;
     652              : 
     653              :   /* If it wasn't used we wouldn't be getting it.  */
     654       183684 :   TREE_USED (decl) = 1;
     655              : 
     656       183684 :   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       183684 :   if (current_function_decl != NULL_TREE)
     664              :     {
     665       164392 :       if (sym->ns->proc_name
     666       164386 :           && (sym->ns->proc_name->backend_decl == current_function_decl
     667        17880 :               || sym->result == sym))
     668       146506 :         gfc_add_decl_to_function (decl);
     669        17886 :       else if (sym->ns->proc_name
     670        17880 :                && sym->ns->proc_name->attr.flavor == FL_LABEL)
     671              :         /* This is a BLOCK construct.  */
     672        12962 :         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       183684 :   if (sym->attr.cray_pointee)
     681              :     return;
     682              : 
     683       183396 :   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       183396 :   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       183284 :   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       183283 :   else if (sym->module && !sym->attr.result && !sym->attr.dummy)
     720              :     {
     721              :       /* TODO: Don't set sym->module for result or dummy variables.  */
     722        19283 :       gcc_assert (current_function_decl == NULL_TREE || sym->result == sym);
     723              : 
     724        19283 :       TREE_PUBLIC (decl) = 1;
     725        19283 :       TREE_STATIC (decl) = 1;
     726        19283 :       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       183396 :   if (!sym->attr.use_assoc
     740       183287 :         && (sym->attr.save != SAVE_NONE || sym->attr.data
     741       147817 :             || (sym->value && sym->ns->proc_name->attr.is_main_program)
     742       143513 :             || (flag_coarray == GFC_FCOARRAY_LIB
     743         2346 :                 && sym->attr.codimension && !sym->attr.allocatable)))
     744        39947 :     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       183396 :   if (!sym->attr.use_assoc
     750       183287 :       && ((sym->ts.type == BT_DERIVED
     751        35498 :            && sym->ts.u.derived->attr.has_dtio_procs)
     752       182696 :           || (sym->ts.type == BT_CLASS
     753         4799 :               && 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       183396 :   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       183390 :   if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive)
     767       160782 :       && !sym->attr.automatic
     768       160769 :       && !sym->attr.associate_var
     769       152573 :       && sym->attr.save != SAVE_EXPLICIT
     770       148888 :       && sym->attr.save != SAVE_IMPLICIT
     771       119160 :       && INTEGER_CST_P (DECL_SIZE_UNIT (decl))
     772       118769 :       && !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       183535 :       && !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       183396 :   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       183396 :   if (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK))
     851            1 :     declare_weak (decl);
     852              : 
     853              :   /* Handle threadprivate variables.  */
     854       183396 :   if (sym->attr.threadprivate
     855       183396 :       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
     856          151 :     set_decl_tls_model (decl, decl_default_tls_model (decl));
     857              : 
     858       183396 :   gfc_finish_decl_attrs (decl, &sym->attr);
     859              : }
     860              : 
     861              : 
     862              : /* Allocate the lang-specific part of a decl.  */
     863              : 
     864              : void
     865       107706 : gfc_allocate_lang_decl (tree decl)
     866              : {
     867       107706 :   if (DECL_LANG_SPECIFIC (decl) == NULL)
     868       102437 :     DECL_LANG_SPECIFIC (decl) = ggc_cleared_alloc<struct lang_decl> ();
     869       107706 : }
     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        82339 : gfc_defer_symbol_init (gfc_symbol * sym)
     889              : {
     890        82339 :   gfc_symbol *p;
     891        82339 :   gfc_symbol *last;
     892        82339 :   gfc_symbol *head;
     893              : 
     894              :   /* Don't add a symbol twice.  */
     895        82339 :   if (sym->tlink)
     896              :     return;
     897              : 
     898        76846 :   last = head = sym->ns->proc_name;
     899        76846 :   p = last->tlink;
     900              : 
     901        76846 :   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        76846 :   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        16670 :              && (!p->attr.dummy || decl_order (p, sym)))
     911              :         {
     912         3283 :           last = p;
     913         3283 :           p = p->tlink;
     914              :         }
     915              :     }
     916        63459 :   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        76846 :   last->tlink = sym;
     932        76846 :   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        13888 : gfc_get_module_backend_decl (gfc_symbol *sym)
     944              : {
     945        13888 :   gfc_gsymbol *gsym;
     946        13888 :   gfc_symbol *s;
     947        13888 :   gfc_symtree *st;
     948              : 
     949        13888 :   gsym =  gfc_find_gsymbol (gfc_gsym_root, sym->module);
     950              : 
     951        13888 :   if (!gsym || (gsym->ns && gsym->type == GSYM_MODULE))
     952              :     {
     953        13888 :       st = NULL;
     954        13888 :       s = NULL;
     955              : 
     956              :       /* Check for a symbol with the same name. */
     957          361 :       if (gsym)
     958        13527 :         gfc_find_symbol (sym->name, gsym->ns, 0, &s);
     959              : 
     960        13888 :       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        13359 :       else if (gfc_fl_struct (sym->attr.flavor))
     974              :         {
     975        10669 :           if (s && s->attr.flavor == FL_PROCEDURE)
     976              :             {
     977         5771 :               gfc_interface *intr;
     978         5771 :               gcc_assert (s->attr.generic);
     979         5916 :               for (intr = s->generic; intr; intr = intr->next)
     980         5916 :                 if (gfc_fl_struct (intr->sym->attr.flavor))
     981              :                   {
     982         5771 :                     s = intr->sym;
     983         5771 :                     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        10669 :           if (sym->attr.flavor == FL_STRUCT && s->ts.type == BT_DERIVED)
     993              :             {
     994            0 :               s = s->ts.u.derived;
     995              :             }
     996              : 
     997        10669 :           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        10669 :           gfc_copy_dt_decls_ifequal (s, sym, true);
    1005        10669 :           return true;
    1006              :         }
    1007         2690 :       else if (s->backend_decl)
    1008              :         {
    1009         2678 :           if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
    1010          532 :             gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
    1011              :                                        true);
    1012         2146 :           else if (sym->ts.type == BT_CHARACTER)
    1013          312 :             sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
    1014         2678 :           sym->backend_decl = s->backend_decl;
    1015         2678 :           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        45375 : create_index_var (const char * pfx, int nest)
    1026              : {
    1027        45375 :   tree decl;
    1028              : 
    1029        45375 :   decl = gfc_create_var_np (gfc_array_index_type, pfx);
    1030        45375 :   if (nest)
    1031           28 :     gfc_add_decl_to_parent_function (decl);
    1032              :   else
    1033        45347 :     gfc_add_decl_to_function (decl);
    1034        45375 :   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        62572 : gfc_build_qualified_array (tree decl, gfc_symbol * sym)
    1044              : {
    1045        62572 :   tree type;
    1046        62572 :   int dim;
    1047        62572 :   int nest;
    1048        62572 :   gfc_namespace* procns;
    1049        62572 :   symbol_attribute *array_attr;
    1050        62572 :   gfc_array_spec *as;
    1051        62572 :   bool is_classarray = IS_CLASS_COARRAY_OR_ARRAY (sym);
    1052              : 
    1053        62572 :   type = TREE_TYPE (decl);
    1054        62572 :   array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
    1055        62572 :   as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
    1056              : 
    1057              :   /* We just use the descriptor, if there is one.  */
    1058        62572 :   if (GFC_DESCRIPTOR_TYPE_P (type))
    1059              :     return;
    1060              : 
    1061        46988 :   gcc_assert (GFC_ARRAY_TYPE_P (type));
    1062        46988 :   procns = gfc_find_proc_namespace (sym->ns);
    1063        93976 :   nest = (procns->proc_name->backend_decl != current_function_decl)
    1064        46988 :          && !sym->attr.contained;
    1065              : 
    1066          846 :   if (array_attr->codimension && flag_coarray == GFC_FCOARRAY_LIB
    1067          535 :       && as->type != AS_ASSUMED_SHAPE
    1068        47500 :       && 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       112012 :   for (dim = 0; dim < GFC_TYPE_ARRAY_RANK (type); dim++)
    1123              :     {
    1124        65024 :       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        65024 :       if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
    1131        65024 :           && (as->type != AS_ASSUMED_SIZE
    1132         2111 :               || dim < GFC_TYPE_ARRAY_RANK (type) - 1))
    1133              :         {
    1134        18444 :           GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var ("ubound", nest);
    1135        18444 :           suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim));
    1136              :         }
    1137              : 
    1138        65024 :       if (GFC_TYPE_ARRAY_STRIDE (type, dim) == NULL_TREE)
    1139              :         {
    1140        11024 :           GFC_TYPE_ARRAY_STRIDE (type, dim) = create_index_var ("stride", nest);
    1141        11024 :           suppress_warning (GFC_TYPE_ARRAY_STRIDE (type, dim));
    1142              :         }
    1143              :     }
    1144        48108 :   for (dim = GFC_TYPE_ARRAY_RANK (type);
    1145        48108 :        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        46988 :   if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE)
    1161              :     {
    1162         8525 :       GFC_TYPE_ARRAY_OFFSET (type) = gfc_create_var_np (gfc_array_index_type,
    1163              :                                                         "offset");
    1164         8525 :       suppress_warning (GFC_TYPE_ARRAY_OFFSET (type));
    1165              : 
    1166         8525 :       if (nest)
    1167            8 :         gfc_add_decl_to_parent_function (GFC_TYPE_ARRAY_OFFSET (type));
    1168              :       else
    1169         8517 :         gfc_add_decl_to_function (GFC_TYPE_ARRAY_OFFSET (type));
    1170              :     }
    1171              : 
    1172        63955 :   if (GFC_TYPE_ARRAY_SIZE (type) == NULL_TREE && as->rank != 0
    1173        63914 :       && as->type != AS_ASSUMED_SIZE)
    1174              :     {
    1175        15212 :       GFC_TYPE_ARRAY_SIZE (type) = create_index_var ("size", nest);
    1176        15212 :       suppress_warning (GFC_TYPE_ARRAY_SIZE (type));
    1177              :     }
    1178              : 
    1179        46988 :   if (POINTER_TYPE_P (type))
    1180              :     {
    1181        20504 :       gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (type)));
    1182        20504 :       gcc_assert (TYPE_LANG_SPECIFIC (type)
    1183              :                   == TYPE_LANG_SPECIFIC (TREE_TYPE (type)));
    1184        20504 :       type = TREE_TYPE (type);
    1185              :     }
    1186              : 
    1187        46988 :   if (! COMPLETE_TYPE_P (type) && GFC_TYPE_ARRAY_SIZE (type))
    1188              :     {
    1189        15212 :       tree size, range;
    1190              : 
    1191        45636 :       size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
    1192        15212 :                               GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node);
    1193        15212 :       range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
    1194              :                                 size);
    1195        15212 :       TYPE_DOMAIN (type) = range;
    1196        15212 :       layout_type (type);
    1197              :     }
    1198              : 
    1199        85398 :   if (TYPE_NAME (type) != NULL_TREE && as->rank > 0
    1200        37961 :       && GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1) != NULL_TREE
    1201        83623 :       && VAR_P (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1)))
    1202              :     {
    1203         7075 :       tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
    1204              : 
    1205         7463 :       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         7075 :       gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
    1211         7075 :       if (TYPE_MAX_VALUE (TYPE_DOMAIN (gtype)) == NULL)
    1212         7075 :         TYPE_NAME (type) = NULL_TREE;
    1213              :     }
    1214              : 
    1215        46988 :   if (TYPE_NAME (type) == NULL_TREE)
    1216              :     {
    1217        15653 :       tree gtype = TREE_TYPE (type), rtype, type_decl;
    1218              : 
    1219        36042 :       for (dim = as->rank - 1; dim >= 0; dim--)
    1220              :         {
    1221        20389 :           tree lbound, ubound;
    1222        20389 :           lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
    1223        20389 :           ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
    1224        20389 :           rtype = build_range_type (gfc_array_index_type, lbound, ubound);
    1225        20389 :           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        20389 :           if (lbound
    1232        20389 :               && VAR_P (lbound)
    1233          521 :               && DECL_ARTIFICIAL (lbound)
    1234        20910 :               && 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        20389 :           if (ubound
    1243        20001 :               && VAR_P (ubound)
    1244        18444 :               && DECL_ARTIFICIAL (ubound)
    1245        38833 :               && DECL_IGNORED_P (ubound))
    1246              :             {
    1247        18444 :               if (DECL_NAME (ubound)
    1248        18444 :                   && strstr (IDENTIFIER_POINTER (DECL_NAME (ubound)),
    1249              :                              "ubound") != 0)
    1250        18444 :                 DECL_NAMELESS (ubound) = 1;
    1251        18444 :               DECL_IGNORED_P (ubound) = 0;
    1252              :             }
    1253              :         }
    1254        15653 :       TYPE_NAME (type) = type_decl = build_decl (input_location,
    1255              :                                                  TYPE_DECL, NULL, gtype);
    1256        15653 :       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        24782 : gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
    1267              : {
    1268        24782 :   tree decl;
    1269        24782 :   tree type;
    1270        24782 :   gfc_array_spec *as;
    1271        24782 :   symbol_attribute *array_attr;
    1272        24782 :   char *name;
    1273        24782 :   gfc_packed packed;
    1274        24782 :   int n;
    1275        24782 :   bool known_size;
    1276        24782 :   bool is_classarray = IS_CLASS_COARRAY_OR_ARRAY (sym);
    1277              : 
    1278              :   /* Use the array as and attr.  */
    1279        24782 :   as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
    1280        24782 :   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        24782 :   if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
    1287        22917 :       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
    1288        22917 :       || array_attr->allocatable
    1289        17856 :       || (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        14097 :   if (sym->attr.result || sym->attr.dummy)
    1295        13493 :     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        14097 :   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        14097 :   gcc_assert (TREE_CODE (dummy) == PARM_DECL
    1304              :           && POINTER_TYPE_P (TREE_TYPE (dummy)));
    1305              : 
    1306              :   /* Do we know the element size?  */
    1307        14097 :   known_size = sym->ts.type != BT_CHARACTER
    1308        14097 :           || INTEGER_CST_P (sym->ts.u.cl->backend_decl);
    1309              : 
    1310        13217 :   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         7356 :   if (GFC_DESCRIPTOR_TYPE_P (type))
    1319              :     {
    1320              :       /* Create a descriptorless array pointer.  */
    1321         6987 :       packed = PACKED_NO;
    1322              : 
    1323              :       /* Even when -frepack-arrays is used, symbols with TARGET attribute
    1324              :          are not repacked.  */
    1325         6987 :       if (!flag_repack_arrays || sym->attr.target)
    1326              :         {
    1327         6985 :           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         6987 :       type = is_classarray ? gfc_get_element_type (type)
    1354         6125 :                            : gfc_typenode_for_spec (&sym->ts);
    1355         6987 :       type = gfc_get_nodesc_array_type (type, as, packed,
    1356         6987 :                                         !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         7356 :   ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0);
    1370         7356 :   decl = build_decl (input_location,
    1371              :                      VAR_DECL, get_identifier (name), type);
    1372              : 
    1373         7356 :   DECL_ARTIFICIAL (decl) = 1;
    1374         7356 :   DECL_NAMELESS (decl) = 1;
    1375         7356 :   TREE_PUBLIC (decl) = 0;
    1376         7356 :   TREE_STATIC (decl) = 0;
    1377         7356 :   DECL_EXTERNAL (decl) = 0;
    1378              : 
    1379              :   /* Avoid uninitialized warnings for optional dummy arguments.  */
    1380         7356 :   if ((sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.optional)
    1381         7356 :       || 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         7356 :   gcc_assert (as->type != AS_DEFERRED);
    1387              : 
    1388         7356 :   if (packed == PACKED_PARTIAL)
    1389            1 :     GFC_DECL_PARTIAL_PACKED_ARRAY (decl) = 1;
    1390         7355 :   else if (packed == PACKED_FULL)
    1391          448 :     GFC_DECL_PACKED_ARRAY (decl) = 1;
    1392              : 
    1393         7356 :   gfc_build_qualified_array (decl, sym);
    1394              : 
    1395         7356 :   if (DECL_LANG_SPECIFIC (dummy))
    1396          982 :     DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (dummy);
    1397              :   else
    1398         6374 :     gfc_allocate_lang_decl (decl);
    1399              : 
    1400         7356 :   GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
    1401              : 
    1402         7356 :   if (sym->ns->proc_name->backend_decl == current_function_decl
    1403          518 :       || sym->attr.contained)
    1404         7348 :     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       285784 : add_attributes_to_decl (tree *decl_p, const gfc_symbol *sym)
    1512              : {
    1513       285784 :   unsigned id;
    1514       285784 :   tree list = NULL_TREE;
    1515       285784 :   symbol_attribute sym_attr = sym->attr;
    1516              : 
    1517      3143624 :   for (id = 0; id < EXT_ATTR_NUM; id++)
    1518      2857840 :     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       285784 :   tree clauses = NULL_TREE;
    1525              : 
    1526       285784 :   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       285784 :   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       285784 :   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       285784 :   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       285778 :   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       285784 :   bool has_declare = true;
    1599       285784 :   if (sym_attr.omp_declare_target_link
    1600       285776 :       || sym_attr.oacc_declare_link)
    1601            9 :     list = tree_cons (get_identifier ("omp declare target link"),
    1602              :                       clauses, list);
    1603       285775 :   else if (sym_attr.omp_declare_target
    1604       284901 :            || sym_attr.oacc_declare_create
    1605       284858 :            || sym_attr.oacc_declare_copyin
    1606       284848 :            || sym_attr.oacc_declare_deviceptr
    1607       284848 :            || 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       285784 :   if (sym_attr.omp_declare_target_indirect)
    1614           46 :     list = tree_cons (get_identifier ("omp declare target indirect"),
    1615              :                       clauses, list);
    1616              : 
    1617       285784 :   decl_attributes (decl_p, list, 0);
    1618              : 
    1619       285784 :   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       285784 : }
    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      1828080 : gfc_get_symbol_decl (gfc_symbol * sym)
    1660              : {
    1661      1828080 :   tree decl;
    1662      1828080 :   tree length = NULL_TREE;
    1663      1828080 :   int byref;
    1664      1828080 :   bool intrinsic_array_parameter = false;
    1665      1828080 :   bool fun_or_res;
    1666              : 
    1667      1828080 :   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       324852 :   if (sym->attr.dummy && sym->ns->proc_name->attr.is_bind_c
    1676      1852043 :       && 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      1812591 :   if (sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.function)
    1684       224311 :     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      1812591 :   if (sym->ts.type == BT_CLASS)
    1690              :     {
    1691        85032 :       gfc_component *c = CLASS_DATA (sym);
    1692        85032 :       if (!c->ts.u.derived->backend_decl)
    1693              :         {
    1694         2541 :           gfc_find_derived_vtab (c->ts.u.derived);
    1695         2541 :           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      1812591 :   if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
    1703       318761 :       && sym->param_list != NULL
    1704         4259 :       && (gfc_current_ns == sym->ns
    1705         2071 :           || (gfc_current_ns == sym->ns->parent
    1706         2071 :               && gfc_current_ns->proc_name->attr.flavor != FL_MODULE))
    1707         3032 :       && !(sym->attr.use_assoc || sym->attr.dummy))
    1708         2773 :     gfc_defer_symbol_init (sym);
    1709              : 
    1710      1812591 :   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      1812591 :   if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
    1719       318761 :       && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
    1720        10838 :       && 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      1812591 :   if (!byref && sym->attr.function
    1728        19052 :         && 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        17400 :   fun_or_res = byref && (sym->attr.result
    1740        13647 :                          || (sym->attr.function && sym->ts.deferred));
    1741      1812591 :   if ((sym->attr.dummy && ! sym->attr.function) || fun_or_res)
    1742              :     {
    1743              :       /* Return via extra parameter.  */
    1744       312562 :       if (sym->attr.result && byref
    1745         3753 :           && !sym->backend_decl)
    1746              :         {
    1747         2392 :           sym->backend_decl =
    1748         1196 :             DECL_ARGUMENTS (sym->ns->proc_name->backend_decl);
    1749              :           /* For entry master function skip over the __entry
    1750              :              argument.  */
    1751         1196 :           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       312562 :       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       312562 :       gcc_assert (sym->backend_decl);
    1772              : 
    1773              :       /* However, the string length of deferred arrays must be set.  */
    1774       312562 :       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       312562 :       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       312562 :       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       312562 :       if ((sym->attr.dimension || sym->attr.codimension)
    1853       107020 :          && !TREE_USED (sym->backend_decl))
    1854              :         {
    1855        19771 :           decl = gfc_build_dummy_array_decl (sym, sym->backend_decl);
    1856              :           /* Prevent the dummy from being detected as unused if it is copied.  */
    1857        19771 :           if (sym->backend_decl != NULL && decl != sym->backend_decl)
    1858         5521 :             DECL_ARTIFICIAL (sym->backend_decl) = 1;
    1859        19771 :           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        26800 :       if (IS_CLASS_COARRAY_OR_ARRAY (sym)
    1869       322749 :           && (!DECL_LANG_SPECIFIC (sym->backend_decl)
    1870         7865 :               || !GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl)))
    1871              :         {
    1872         4204 :           decl = gfc_build_dummy_array_decl (sym, sym->backend_decl);
    1873              :           /* Prevent the dummy from being detected as unused if it is copied.  */
    1874         4204 :           if (sym->backend_decl != NULL && decl != sym->backend_decl)
    1875          862 :             DECL_ARTIFICIAL (sym->backend_decl) = 1;
    1876         4204 :           sym->backend_decl = decl;
    1877              :         }
    1878              : 
    1879       312562 :       TREE_USED (sym->backend_decl) = 1;
    1880       312562 :       if (sym->attr.assign && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
    1881            6 :         gfc_add_assign_aux_vars (sym);
    1882              : 
    1883       312562 :       if (sym->ts.type == BT_CLASS && sym->backend_decl
    1884        26800 :           && !IS_CLASS_COARRAY_OR_ARRAY (sym))
    1885        16613 :         GFC_DECL_CLASS (sym->backend_decl) = 1;
    1886              : 
    1887       312562 :       return sym->backend_decl;
    1888              :     }
    1889              : 
    1890        15636 :   if (sym->result == sym && sym->attr.assign
    1891      1500034 :       && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
    1892            1 :     gfc_add_assign_aux_vars (sym);
    1893              : 
    1894      1500029 :   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       198322 :   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       198322 :     intrinsic_array_parameter = true;
    1903              : 
    1904              :   /* If use associated compilation, use the module
    1905              :      declaration.  */
    1906       198322 :   if ((sym->attr.flavor == FL_VARIABLE
    1907        16979 :        || sym->attr.flavor == FL_PARAMETER)
    1908       182896 :       && (sym->attr.use_assoc || sym->attr.used_in_submodule)
    1909         2802 :       && !intrinsic_array_parameter
    1910         2793 :       && sym->module
    1911       201115 :       && gfc_get_module_backend_decl (sym))
    1912              :     {
    1913         2678 :       if (sym->ts.type == BT_CLASS && sym->backend_decl)
    1914           39 :         GFC_DECL_CLASS(sym->backend_decl) = 1;
    1915         2678 :       return sym->backend_decl;
    1916              :     }
    1917              : 
    1918       195644 :   if (sym->attr.flavor == FL_PROCEDURE)
    1919              :     {
    1920              :       /* Catch functions. Only used for actual parameters,
    1921              :          procedure pointers and procptr initialization targets.  */
    1922        15300 :       if (sym->attr.use_assoc
    1923        14472 :           || sym->attr.used_in_submodule
    1924        14466 :           || sym->attr.intrinsic
    1925        13175 :           || sym->attr.if_source != IFSRC_DECL)
    1926              :         {
    1927         3107 :           decl = gfc_get_extern_function_decl (sym);
    1928              :         }
    1929              :       else
    1930              :         {
    1931        12193 :           if (!sym->backend_decl)
    1932        12193 :             build_function_decl (sym, false);
    1933        12193 :           decl = sym->backend_decl;
    1934              :         }
    1935        15300 :       return decl;
    1936              :     }
    1937              : 
    1938       180344 :   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       180344 :   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       180344 :   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       180344 :   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       180344 :   if (sym->module || sym->fn_result_spec)
    1976              :     {
    1977        19354 :       gfc_set_decl_assembler_name (decl, gfc_sym_mangled_identifier (sym));
    1978        19354 :       if (sym->attr.use_assoc && !intrinsic_array_parameter)
    1979          112 :         DECL_IGNORED_P (decl) = 1;
    1980              :     }
    1981              : 
    1982       180344 :   if (sym->attr.select_type_temporary)
    1983              :     {
    1984         5654 :       DECL_ARTIFICIAL (decl) = 1;
    1985         5654 :       DECL_IGNORED_P (decl) = 1;
    1986              :     }
    1987              : 
    1988       180344 :   if (sym->attr.dimension || sym->attr.codimension)
    1989              :     {
    1990              :       /* Create variables to hold the non-constant bits of array info.  */
    1991        48221 :       gfc_build_qualified_array (decl, sym);
    1992              : 
    1993        48221 :       if (sym->attr.contiguous
    1994        48152 :           || ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer))
    1995        43485 :         GFC_DECL_PACKED_ARRAY (decl) = 1;
    1996              :     }
    1997              : 
    1998              :   /* Remember this variable for allocation/cleanup.  */
    1999       132573 :   if (sym->attr.dimension || sym->attr.allocatable || sym->attr.codimension
    2000       129822 :       || (sym->ts.type == BT_CLASS &&
    2001         4799 :           (CLASS_DATA (sym)->attr.dimension
    2002         2700 :            || CLASS_DATA (sym)->attr.allocatable))
    2003       126293 :       || (sym->ts.type == BT_DERIVED
    2004        30070 :           && (sym->ts.u.derived->attr.alloc_comp
    2005        23755 :               || (!sym->attr.pointer && !sym->attr.artificial && !sym->attr.save
    2006         5245 :                   && !sym->ns->proc_name->attr.is_main_program
    2007         2134 :                   && gfc_is_finalizable (sym->ts.u.derived, NULL))))
    2008              :       /* This applies a derived type default initializer.  */
    2009       300073 :       || (sym->ts.type == BT_DERIVED
    2010        23506 :           && sym->attr.save == SAVE_NONE
    2011         6558 :           && !sym->attr.data
    2012         6509 :           && !sym->attr.allocatable
    2013         6509 :           && (sym->value && !sym->ns->proc_name->attr.is_main_program)
    2014          522 :           && !(sym->attr.use_assoc && !intrinsic_array_parameter)))
    2015        61137 :     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       180344 :   if (sym->ts.type == BT_CLASS && UNLIMITED_POLY (sym)
    2021         1114 :       && CLASS_DATA (sym)->attr.class_pointer
    2022          679 :       && !CLASS_DATA (sym)->attr.dimension && !sym->attr.dummy
    2023          303 :       && sym->attr.flavor == FL_VARIABLE && !sym->assoc)
    2024          172 :     gfc_defer_symbol_init (sym);
    2025              : 
    2026       180344 :   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       180344 :   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       180344 :   gfc_finish_var_decl (decl, sym);
    2058              : 
    2059       180344 :   if (sym->ts.type == BT_CHARACTER)
    2060              :     /* Character variables need special handling.  */
    2061        15751 :     gfc_allocate_lang_decl (decl);
    2062              : 
    2063       180344 :   if (sym->assoc && sym->attr.subref_array_pointer)
    2064          392 :     sym->attr.pointer = 1;
    2065              : 
    2066       180344 :   if (sym->attr.pointer && sym->attr.dimension
    2067         4903 :       && !sym->ts.deferred
    2068         4614 :       && !(sym->attr.select_type_temporary
    2069         1088 :            && !sym->attr.subref_array_pointer))
    2070         3676 :     GFC_DECL_PTR_ARRAY_P (decl) = 1;
    2071              : 
    2072       180344 :   if (sym->ts.type == BT_CLASS)
    2073         4799 :     GFC_DECL_CLASS(decl) = 1;
    2074              : 
    2075       180344 :   sym->backend_decl = decl;
    2076              : 
    2077       180344 :   if (sym->attr.assign)
    2078           59 :     gfc_add_assign_aux_vars (sym);
    2079              : 
    2080       180344 :   if (intrinsic_array_parameter)
    2081              :     {
    2082            9 :       TREE_STATIC (decl) = 1;
    2083            9 :       DECL_EXTERNAL (decl) = 0;
    2084              :     }
    2085              : 
    2086       180344 :   if (TREE_STATIC (decl)
    2087        40601 :       && !(sym->attr.use_assoc && !intrinsic_array_parameter)
    2088        40601 :       && (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        40431 :       && (flag_coarray != GFC_FCOARRAY_LIB
    2092         2128 :           || !sym->attr.codimension || sym->attr.allocatable)
    2093       220434 :       && !(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        39553 :       DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
    2101        39553 :                                     TREE_TYPE (decl), sym->attr.dimension
    2102        39553 :                                     || (sym->attr.codimension
    2103           35 :                                         && sym->attr.allocatable),
    2104        39026 :                                     sym->attr.pointer || sym->attr.allocatable
    2105        38613 :                                     || sym->ts.type == BT_CLASS,
    2106        39553 :                                     sym->attr.proc_pointer);
    2107              :     }
    2108              : 
    2109       180344 :   if (!TREE_STATIC (decl)
    2110       139743 :       && POINTER_TYPE_P (TREE_TYPE (decl))
    2111        18338 :       && !sym->attr.pointer
    2112        12601 :       && !sym->attr.allocatable
    2113        10411 :       && !sym->attr.proc_pointer
    2114       190755 :       && !sym->attr.select_type_temporary)
    2115         7964 :     DECL_BY_REFERENCE (decl) = 1;
    2116              : 
    2117       180344 :   if (sym->attr.associate_var)
    2118         7220 :     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       180344 :   bool def_init = startswith (sym->name, "__def_init");
    2127              : 
    2128       180344 :   if (sym->attr.vtab || def_init)
    2129              :     {
    2130        19459 :       DECL_ARTIFICIAL (decl) = 1;
    2131        19459 :       if (def_init && sym->value)
    2132         3561 :         TREE_READONLY (decl) = 1;
    2133              :     }
    2134              : 
    2135              :   /* Add attributes to variables.  Functions are handled elsewhere.  */
    2136       180344 :   add_attributes_to_decl (&decl, sym);
    2137              : 
    2138       180344 :   if (sym->ts.deferred && VAR_P (length))
    2139         1828 :     decl_attributes (&length, DECL_ATTRIBUTES (decl), 0);
    2140              : 
    2141       180344 :   return decl;
    2142              : }
    2143              : 
    2144              : 
    2145              : /* Substitute a temporary variable in place of the real one.  */
    2146              : 
    2147              : void
    2148         5828 : gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save)
    2149              : {
    2150         5828 :   save->attr = sym->attr;
    2151         5828 :   save->decl = sym->backend_decl;
    2152              : 
    2153         5828 :   gfc_clear_attr (&sym->attr);
    2154         5828 :   sym->attr.referenced = 1;
    2155         5828 :   sym->attr.flavor = FL_VARIABLE;
    2156              : 
    2157         5828 :   sym->backend_decl = decl;
    2158         5828 : }
    2159              : 
    2160              : 
    2161              : /* Restore the original variable.  */
    2162              : 
    2163              : void
    2164         5828 : gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
    2165              : {
    2166         5828 :   sym->attr = save->attr;
    2167         5828 :   sym->backend_decl = save->decl;
    2168         5828 : }
    2169              : 
    2170              : 
    2171              : /* Declare a procedure pointer.  */
    2172              : 
    2173              : static tree
    2174          691 : get_proc_pointer_decl (gfc_symbol *sym)
    2175              : {
    2176          691 :   tree decl;
    2177              : 
    2178          691 :   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          612 :   decl = sym->backend_decl;
    2195          612 :   if (decl)
    2196              :     return decl;
    2197              : 
    2198          612 :   decl = build_decl (input_location,
    2199              :                      VAR_DECL, get_identifier (sym->name),
    2200              :                      build_pointer_type (gfc_get_function_type (sym)));
    2201              : 
    2202          612 :   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          612 :   if ((sym->ns->proc_name
    2211          612 :       && sym->ns->proc_name->backend_decl == current_function_decl)
    2212           76 :       || sym->attr.contained)
    2213          536 :     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          612 :   sym->backend_decl = decl;
    2218              : 
    2219              :   /* If a variable is USE associated, it's always external.  */
    2220          612 :   if (sym->attr.use_assoc)
    2221              :     {
    2222            0 :       DECL_EXTERNAL (decl) = 1;
    2223            0 :       TREE_PUBLIC (decl) = 1;
    2224              :     }
    2225          612 :   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          612 :   if (!sym->attr.use_assoc
    2238          612 :         && (sym->attr.save != SAVE_NONE || sym->attr.data
    2239          491 :               || (sym->value && sym->ns->proc_name->attr.is_main_program)))
    2240          121 :     TREE_STATIC (decl) = 1;
    2241              : 
    2242          612 :   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          612 :   add_attributes_to_decl (&decl, sym);
    2252              : 
    2253              :   /* Handle threadprivate procedure pointers.  */
    2254          612 :   if (sym->attr.threadprivate
    2255          612 :       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    2256           12 :     set_decl_tls_model (decl, decl_default_tls_model (decl));
    2257              : 
    2258          612 :   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        36615 : gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args,
    2268              :                               const char *fnspec)
    2269              : {
    2270        36615 :   tree type;
    2271        36615 :   tree fndecl;
    2272        36615 :   gfc_expr e;
    2273        36615 :   gfc_intrinsic_sym *isym;
    2274        36615 :   gfc_expr argexpr;
    2275        36615 :   char s[GFC_MAX_SYMBOL_LEN + 23]; /* "_gfortran_f2c_specific" and '\0'.  */
    2276        36615 :   tree name;
    2277        36615 :   tree mangled_name;
    2278        36615 :   gfc_gsymbol *gsym;
    2279              : 
    2280        36615 :   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        36615 :   gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
    2287              : 
    2288        36615 :   if (sym->attr.proc_pointer)
    2289          691 :     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        35924 :   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        33357 :   else if (sym->module == NULL)
    2303              :     {
    2304        19878 :       gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
    2305        19878 :       if (gsym && gsym->bind_c)
    2306              :         gsym = NULL;
    2307              :     }
    2308              :   else
    2309              :     {
    2310              :       /* Procedure from a different module.  */
    2311              :       gsym = NULL;
    2312              :     }
    2313              : 
    2314        10940 :   if (gsym && !gsym->defined)
    2315              :     gsym = NULL;
    2316              : 
    2317              :   /* This can happen because of C binding.  */
    2318         7805 :   if (gsym && gsym->ns && gsym->ns->proc_name
    2319         7805 :       && gsym->ns->proc_name->attr.flavor == FL_MODULE)
    2320          557 :     goto module_sym;
    2321              : 
    2322        35367 :   if ((!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL)
    2323        25624 :       && !sym->backend_decl
    2324        25624 :       && gsym && gsym->ns
    2325         7248 :       && ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION))
    2326         7248 :       && (gsym->ns->proc_name->backend_decl || !sym->attr.intrinsic))
    2327              :     {
    2328         7248 :       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         7248 :       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         6451 :         sym->backend_decl = gsym->ns->proc_name->backend_decl;
    2359              : 
    2360         7248 :       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         7248 :           if (sym->attr.if_source != IFSRC_DECL && sym->attr.use_assoc)
    2365            0 :             sym->attr.use_assoc = 0;
    2366              : 
    2367         7248 :           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        28119 :   if (sym->module)
    2374        14349 :     gsym =  gfc_find_gsymbol (gfc_gsym_root, sym->module);
    2375              : 
    2376        28676 : module_sym:
    2377        28676 :   if (gsym && gsym->ns
    2378        11532 :       && (gsym->type == GSYM_MODULE
    2379          557 :           || (gsym->ns->proc_name && gsym->ns->proc_name->attr.flavor == FL_MODULE)))
    2380              :     {
    2381        11532 :       gfc_symbol *s;
    2382              : 
    2383        11532 :       s = NULL;
    2384        11532 :       if (gsym->type == GSYM_MODULE)
    2385        10975 :         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        11532 :       if (s && s->backend_decl)
    2390              :         {
    2391         9504 :           if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
    2392         1156 :             gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
    2393              :                                        true);
    2394         8348 :           else if (sym->ts.type == BT_CHARACTER)
    2395          411 :             sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
    2396         9504 :           sym->backend_decl = s->backend_decl;
    2397         9504 :           return sym->backend_decl;
    2398              :         }
    2399              :     }
    2400              : 
    2401        19172 :   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        17880 :       name = gfc_sym_identifier (sym);
    2453        17880 :       mangled_name = gfc_sym_mangled_function_id (sym);
    2454              :     }
    2455              : 
    2456        19172 :   type = gfc_get_function_type (sym, actual_args, fnspec);
    2457              : 
    2458        19172 :   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        19172 :   DECL_EXTERNAL (fndecl) = 1;
    2465        19172 :   TREE_PUBLIC (fndecl) = 1;
    2466              : 
    2467        19172 :   add_attributes_to_decl (&fndecl, sym);
    2468              : 
    2469        19172 :   gfc_set_decl_assembler_name (fndecl, mangled_name);
    2470              : 
    2471              :   /* Set the context of this decl.  */
    2472        19172 :   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        19172 :       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        19172 :   if (sym->attr.pure || sym->attr.implicit_pure)
    2487              :     {
    2488         2084 :       if (sym->attr.function && !gfc_return_by_reference (sym))
    2489         1854 :         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         2084 :       TREE_SIDE_EFFECTS (fndecl) = 0;
    2495              :     }
    2496              : 
    2497              :   /* Mark non-returning functions.  */
    2498        19172 :   if (sym->attr.noreturn || sym->attr.ext_attr & (1 << EXT_ATTR_NORETURN))
    2499          111 :       TREE_THIS_VOLATILE(fndecl) = 1;
    2500              : 
    2501        19172 :   sym->backend_decl = fndecl;
    2502              : 
    2503        19172 :   if (DECL_CONTEXT (fndecl) == NULL_TREE)
    2504        19172 :     pushdecl_top_level (fndecl);
    2505              : 
    2506        19172 :   if (sym->formal_ns
    2507        17070 :       && sym->formal_ns->proc_name == sym)
    2508              :     {
    2509        17070 :       if (sym->formal_ns->omp_declare_simd)
    2510           15 :         gfc_trans_omp_declare_simd (sym->formal_ns);
    2511        17070 :       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        19172 :   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        97849 : build_function_decl (gfc_symbol * sym, bool global)
    2530              : {
    2531        97849 :   tree fndecl, type;
    2532        97849 :   symbol_attribute attr;
    2533        97849 :   tree result_decl;
    2534        97849 :   gfc_formal_arglist *f;
    2535              : 
    2536       195698 :   bool module_procedure = sym->attr.module_procedure
    2537          446 :                           && sym->ns
    2538          446 :                           && sym->ns->proc_name
    2539        98295 :                           && sym->ns->proc_name->attr.flavor == FL_MODULE;
    2540              : 
    2541        97849 :   gcc_assert (!sym->attr.external || module_procedure);
    2542              : 
    2543        97849 :   if (sym->backend_decl)
    2544        12193 :     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        85656 :   input_location = gfc_get_location (&sym->declared_at);
    2549              : 
    2550              :   /* Allow only one nesting level.  Allow public declarations.  */
    2551        85656 :   gcc_assert (current_function_decl == NULL_TREE
    2552              :               || DECL_FILE_SCOPE_P (current_function_decl)
    2553              :               || (TREE_CODE (DECL_CONTEXT (current_function_decl))
    2554              :                   == FUNCTION_DECL)
    2555              :               || (TREE_CODE (DECL_CONTEXT (current_function_decl))
    2556              :                   == NAMESPACE_DECL));
    2557              : 
    2558        85656 :   type = gfc_get_function_type (sym);
    2559        85656 :   fndecl = build_decl (input_location,
    2560              :                        FUNCTION_DECL, gfc_sym_identifier (sym), type);
    2561              : 
    2562        85656 :   attr = sym->attr;
    2563              : 
    2564              :   /* Initialize DECL_EXTERNAL and TREE_PUBLIC before calling decl_attributes;
    2565              :      TREE_PUBLIC specifies whether a function is globally addressable (i.e.
    2566              :      the opposite of declaring a function as static in C).  */
    2567        85656 :   DECL_EXTERNAL (fndecl) = 0;
    2568              : 
    2569        85656 :   if (sym->attr.access == ACCESS_UNKNOWN && sym->module
    2570        24412 :       && (sym->ns->default_access == ACCESS_PRIVATE
    2571        22464 :           || (sym->ns->default_access == ACCESS_UNKNOWN
    2572        22451 :               && flag_module_private)))
    2573         1948 :     sym->attr.access = ACCESS_PRIVATE;
    2574              : 
    2575        85656 :   if (!current_function_decl
    2576        62747 :       && !sym->attr.entry_master && !sym->attr.is_main_program
    2577        36028 :       && (sym->attr.access != ACCESS_PRIVATE || sym->binding_label
    2578         2138 :           || sym->attr.public_used))
    2579        35241 :     TREE_PUBLIC (fndecl) = 1;
    2580              : 
    2581        85656 :   if (sym->attr.referenced || sym->attr.entry_master)
    2582        39708 :     TREE_USED (fndecl) = 1;
    2583              : 
    2584        85656 :   add_attributes_to_decl (&fndecl, sym);
    2585              : 
    2586              :   /* Figure out the return type of the declared function, and build a
    2587              :      RESULT_DECL for it.  If this is a subroutine with alternate
    2588              :      returns, build a RESULT_DECL for it.  */
    2589        85656 :   result_decl = NULL_TREE;
    2590              :   /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)).  */
    2591        85656 :   if (sym->attr.function)
    2592              :     {
    2593        15905 :       if (gfc_return_by_reference (sym))
    2594         3087 :         type = void_type_node;
    2595              :       else
    2596              :         {
    2597        12818 :           if (sym->result != sym)
    2598         6268 :             result_decl = gfc_sym_identifier (sym->result);
    2599              : 
    2600        12818 :           type = TREE_TYPE (TREE_TYPE (fndecl));
    2601              :         }
    2602              :     }
    2603              :   else
    2604              :     {
    2605              :       /* Look for alternate return placeholders.  */
    2606        69751 :       int has_alternate_returns = 0;
    2607       148349 :       for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    2608              :         {
    2609        78667 :           if (f->sym == NULL)
    2610              :             {
    2611              :               has_alternate_returns = 1;
    2612              :               break;
    2613              :             }
    2614              :         }
    2615              : 
    2616        69751 :       if (has_alternate_returns)
    2617           69 :         type = integer_type_node;
    2618              :       else
    2619        69682 :         type = void_type_node;
    2620              :     }
    2621              : 
    2622        85656 :   result_decl = build_decl (input_location,
    2623              :                             RESULT_DECL, result_decl, type);
    2624        85656 :   DECL_ARTIFICIAL (result_decl) = 1;
    2625        85656 :   DECL_IGNORED_P (result_decl) = 1;
    2626        85656 :   DECL_CONTEXT (result_decl) = fndecl;
    2627        85656 :   DECL_RESULT (fndecl) = result_decl;
    2628              : 
    2629              :   /* Don't call layout_decl for a RESULT_DECL.
    2630              :      layout_decl (result_decl, 0);  */
    2631              : 
    2632              :   /* TREE_STATIC means the function body is defined here.  */
    2633        85656 :   TREE_STATIC (fndecl) = 1;
    2634              : 
    2635              :   /* Set attributes for PURE functions. A call to a PURE function in the
    2636              :      Fortran 95 sense is both pure and without side effects in the C
    2637              :      sense.  */
    2638        85656 :   if (sym->attr.pure || sym->attr.implicit_pure)
    2639              :     {
    2640              :       /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments
    2641              :          including an alternate return. In that case it can also be
    2642              :          marked as PURE. See also in gfc_get_extern_function_decl().  */
    2643        18845 :       if (attr.function && !gfc_return_by_reference (sym))
    2644         4501 :         DECL_PURE_P (fndecl) = 1;
    2645        18845 :       TREE_SIDE_EFFECTS (fndecl) = 0;
    2646              :     }
    2647              : 
    2648              :   /* Mark noinline functions.  */
    2649        85656 :   if (attr.ext_attr & (1 << EXT_ATTR_NOINLINE))
    2650            1 :     DECL_UNINLINABLE (fndecl) = 1;
    2651              : 
    2652              :   /* Mark noreturn functions.  */
    2653        85656 :   if (attr.ext_attr & (1 << EXT_ATTR_NORETURN))
    2654            8 :     TREE_THIS_VOLATILE (fndecl) = 1;
    2655              : 
    2656              :   /* Mark weak functions.  */
    2657        85656 :   if (attr.ext_attr & (1 << EXT_ATTR_WEAK))
    2658            6 :     declare_weak (fndecl);
    2659              : 
    2660              :   /* Layout the function declaration and put it in the binding level
    2661              :      of the current function.  */
    2662              : 
    2663        85656 :   if (global)
    2664          774 :     pushdecl_top_level (fndecl);
    2665              :   else
    2666        84882 :     pushdecl (fndecl);
    2667              : 
    2668              :   /* Perform name mangling if this is a top level or module procedure.  */
    2669        85656 :   if (current_function_decl == NULL_TREE)
    2670        62747 :     gfc_set_decl_assembler_name (fndecl, gfc_sym_mangled_function_id (sym));
    2671              : 
    2672        85656 :   sym->backend_decl = fndecl;
    2673              : }
    2674              : 
    2675              : 
    2676              : /* Create the DECL_ARGUMENTS for a procedure.
    2677              :    NOTE: The arguments added here must match the argument type created by
    2678              :    gfc_get_function_type ().  */
    2679              : 
    2680              : static void
    2681        87468 : create_function_arglist (gfc_symbol * sym)
    2682              : {
    2683        87468 :   tree fndecl;
    2684        87468 :   gfc_formal_arglist *f;
    2685        87468 :   tree typelist, hidden_typelist, optval_typelist;
    2686        87468 :   tree arglist, hidden_arglist, optval_arglist;
    2687        87468 :   tree type;
    2688        87468 :   tree parm;
    2689              : 
    2690        87468 :   fndecl = sym->backend_decl;
    2691              : 
    2692              :   /* Build formal argument list. Make sure that their TREE_CONTEXT is
    2693              :      the new FUNCTION_DECL node.  */
    2694        87468 :   arglist = NULL_TREE;
    2695        87468 :   hidden_arglist = NULL_TREE;
    2696        87468 :   optval_arglist = NULL_TREE;
    2697        87468 :   typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    2698              : 
    2699        87468 :   if (sym->attr.entry_master)
    2700              :     {
    2701          634 :       type = TREE_VALUE (typelist);
    2702          634 :       parm = build_decl (input_location,
    2703              :                          PARM_DECL, get_identifier ("__entry"), type);
    2704              : 
    2705          634 :       DECL_CONTEXT (parm) = fndecl;
    2706          634 :       DECL_ARG_TYPE (parm) = type;
    2707          634 :       TREE_READONLY (parm) = 1;
    2708          634 :       gfc_finish_decl (parm);
    2709          634 :       DECL_ARTIFICIAL (parm) = 1;
    2710              : 
    2711          634 :       arglist = chainon (arglist, parm);
    2712          634 :       typelist = TREE_CHAIN (typelist);
    2713              :     }
    2714              : 
    2715        87468 :   if (gfc_return_by_reference (sym))
    2716              :     {
    2717         3129 :       tree type = TREE_VALUE (typelist), length = NULL;
    2718              : 
    2719         3129 :       if (sym->ts.type == BT_CHARACTER)
    2720              :         {
    2721              :           /* Length of character result.  */
    2722         1590 :           tree len_type = TREE_VALUE (TREE_CHAIN (typelist));
    2723              : 
    2724         1590 :           length = build_decl (input_location,
    2725              :                                PARM_DECL,
    2726              :                                get_identifier (".__result"),
    2727              :                                len_type);
    2728         1590 :           if (POINTER_TYPE_P (len_type))
    2729              :             {
    2730          281 :               sym->ts.u.cl->passed_length = length;
    2731          281 :               TREE_USED (length) = 1;
    2732              :             }
    2733         1309 :           else if (!sym->ts.u.cl->length)
    2734              :             {
    2735          157 :               sym->ts.u.cl->backend_decl = length;
    2736          157 :               TREE_USED (length) = 1;
    2737              :             }
    2738         1590 :           gcc_assert (TREE_CODE (length) == PARM_DECL);
    2739         1590 :           DECL_CONTEXT (length) = fndecl;
    2740         1590 :           DECL_ARG_TYPE (length) = len_type;
    2741         1590 :           TREE_READONLY (length) = 1;
    2742         1590 :           DECL_ARTIFICIAL (length) = 1;
    2743         1590 :           gfc_finish_decl (length);
    2744         1590 :           if (sym->ts.u.cl->backend_decl == NULL
    2745          610 :               || sym->ts.u.cl->backend_decl == length)
    2746              :             {
    2747         1137 :               gfc_symbol *arg;
    2748         1137 :               tree backend_decl;
    2749              : 
    2750         1137 :               if (sym->ts.u.cl->backend_decl == NULL)
    2751              :                 {
    2752          980 :                   tree len = build_decl (input_location,
    2753              :                                          VAR_DECL,
    2754              :                                          get_identifier ("..__result"),
    2755              :                                          gfc_charlen_type_node);
    2756          980 :                   DECL_ARTIFICIAL (len) = 1;
    2757          980 :                   TREE_USED (len) = 1;
    2758          980 :                   sym->ts.u.cl->backend_decl = len;
    2759              :                 }
    2760              : 
    2761              :               /* Make sure PARM_DECL type doesn't point to incomplete type.  */
    2762         1137 :               arg = sym->result ? sym->result : sym;
    2763         1137 :               backend_decl = arg->backend_decl;
    2764              :               /* Temporary clear it, so that gfc_sym_type creates complete
    2765              :                  type.  */
    2766         1137 :               arg->backend_decl = NULL;
    2767         1137 :               type = gfc_sym_type (arg);
    2768         1137 :               arg->backend_decl = backend_decl;
    2769         1137 :               type = build_reference_type (type);
    2770              :             }
    2771              :         }
    2772              : 
    2773         3129 :       parm = build_decl (input_location,
    2774              :                          PARM_DECL, get_identifier ("__result"), type);
    2775              : 
    2776         3129 :       DECL_CONTEXT (parm) = fndecl;
    2777         3129 :       DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
    2778         3129 :       TREE_READONLY (parm) = 1;
    2779         3129 :       DECL_ARTIFICIAL (parm) = 1;
    2780         3129 :       gfc_finish_decl (parm);
    2781              : 
    2782         3129 :       arglist = chainon (arglist, parm);
    2783         3129 :       typelist = TREE_CHAIN (typelist);
    2784              : 
    2785         3129 :       if (sym->ts.type == BT_CHARACTER)
    2786              :         {
    2787         1590 :           gfc_allocate_lang_decl (parm);
    2788         1590 :           arglist = chainon (arglist, length);
    2789         1590 :           typelist = TREE_CHAIN (typelist);
    2790              :         }
    2791              :     }
    2792              : 
    2793        87468 :   hidden_typelist = typelist;
    2794       190743 :   for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    2795       103275 :     if (f->sym != NULL)      /* Ignore alternate returns.  */
    2796       103176 :       hidden_typelist = TREE_CHAIN (hidden_typelist);
    2797              : 
    2798              :   /* Advance hidden_typelist over optional+value argument presence flags.  */
    2799        87468 :   optval_typelist = hidden_typelist;
    2800       190743 :   for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    2801       103275 :     if (f->sym != NULL
    2802       103176 :         && f->sym->attr.optional && f->sym->attr.value
    2803          512 :         && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS)
    2804          512 :       hidden_typelist = TREE_CHAIN (hidden_typelist);
    2805              : 
    2806       190743 :   for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    2807              :     {
    2808       103275 :       char name[GFC_MAX_SYMBOL_LEN + 2];
    2809              : 
    2810              :       /* Ignore alternate returns.  */
    2811       103275 :       if (f->sym == NULL)
    2812           99 :         continue;
    2813              : 
    2814       103176 :       type = TREE_VALUE (typelist);
    2815              : 
    2816       103176 :       if (f->sym->ts.type == BT_CHARACTER
    2817         9552 :           && (!sym->attr.is_bind_c || sym->attr.entry_master))
    2818              :         {
    2819         8230 :           tree len_type = TREE_VALUE (hidden_typelist);
    2820         8230 :           tree length = NULL_TREE;
    2821         8230 :           if (!f->sym->ts.deferred)
    2822         7363 :             gcc_assert (len_type == gfc_charlen_type_node);
    2823              :           else
    2824          867 :             gcc_assert (POINTER_TYPE_P (len_type));
    2825              : 
    2826         8230 :           strcpy (&name[1], f->sym->name);
    2827         8230 :           name[0] = '_';
    2828         8230 :           length = build_decl (input_location,
    2829              :                                PARM_DECL, get_identifier (name), len_type);
    2830              : 
    2831         8230 :           hidden_arglist = chainon (hidden_arglist, length);
    2832         8230 :           DECL_CONTEXT (length) = fndecl;
    2833         8230 :           DECL_ARTIFICIAL (length) = 1;
    2834         8230 :           DECL_ARG_TYPE (length) = len_type;
    2835         8230 :           TREE_READONLY (length) = 1;
    2836         8230 :           gfc_finish_decl (length);
    2837              : 
    2838              :           /* Marking the length DECL_HIDDEN_STRING_LENGTH will lead
    2839              :              to tail calls being disabled.  Only do that if we
    2840              :              potentially have broken callers.  */
    2841         8230 :           if (flag_tail_call_workaround
    2842         8230 :               && f->sym->ts.u.cl
    2843         7710 :               && f->sym->ts.u.cl->length
    2844         2616 :               && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
    2845         2351 :               && (flag_tail_call_workaround == 2
    2846         2351 :                   || f->sym->ns->implicit_interface_calls))
    2847           84 :             DECL_HIDDEN_STRING_LENGTH (length) = 1;
    2848              : 
    2849              :           /* Remember the passed value.  */
    2850         8230 :           if (!f->sym->ts.u.cl ||  f->sym->ts.u.cl->passed_length)
    2851              :             {
    2852              :               /* This can happen if the same type is used for multiple
    2853              :                  arguments. We need to copy cl as otherwise
    2854              :                  cl->passed_length gets overwritten.  */
    2855          622 :               f->sym->ts.u.cl = gfc_new_charlen (f->sym->ns, f->sym->ts.u.cl);
    2856              :             }
    2857         8230 :           f->sym->ts.u.cl->passed_length = length;
    2858              : 
    2859              :           /* Use the passed value for assumed length variables.  */
    2860         8230 :           if (!f->sym->ts.u.cl->length)
    2861              :             {
    2862         5614 :               TREE_USED (length) = 1;
    2863         5614 :               gcc_assert (!f->sym->ts.u.cl->backend_decl);
    2864         5614 :               f->sym->ts.u.cl->backend_decl = length;
    2865              :             }
    2866              : 
    2867         8230 :           hidden_typelist = TREE_CHAIN (hidden_typelist);
    2868              : 
    2869         8230 :           if (f->sym->ts.u.cl->backend_decl == NULL
    2870         7932 :               || f->sym->ts.u.cl->backend_decl == length)
    2871              :             {
    2872         5912 :               if (POINTER_TYPE_P (len_type))
    2873          767 :                 f->sym->ts.u.cl->backend_decl
    2874          767 :                   = build_fold_indirect_ref_loc (input_location, length);
    2875         5145 :               else if (f->sym->ts.u.cl->backend_decl == NULL)
    2876          298 :                 gfc_create_string_length (f->sym);
    2877              : 
    2878              :               /* Make sure PARM_DECL type doesn't point to incomplete type.  */
    2879         5912 :               if (f->sym->attr.flavor == FL_PROCEDURE)
    2880           14 :                 type = build_pointer_type (gfc_get_function_type (f->sym));
    2881              :               else
    2882         5898 :                 type = gfc_sym_type (f->sym);
    2883              :             }
    2884              :         }
    2885              :       /* For scalar intrinsic types or derived types, VALUE passes the value,
    2886              :          hence, the optional status cannot be transferred via a NULL pointer.
    2887              :          Thus, we will use a hidden argument in that case.  */
    2888       103176 :       if (f->sym->attr.optional && f->sym->attr.value
    2889          512 :           && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS)
    2890              :         {
    2891          512 :           tree tmp;
    2892          512 :           strcpy (&name[1], f->sym->name);
    2893          512 :           name[0] = '.';
    2894          512 :           tmp = build_decl (input_location,
    2895              :                             PARM_DECL, get_identifier (name),
    2896              :                             boolean_type_node);
    2897              : 
    2898          512 :           optval_arglist = chainon (optval_arglist, tmp);
    2899          512 :           DECL_CONTEXT (tmp) = fndecl;
    2900          512 :           DECL_ARTIFICIAL (tmp) = 1;
    2901          512 :           DECL_ARG_TYPE (tmp) = boolean_type_node;
    2902          512 :           TREE_READONLY (tmp) = 1;
    2903          512 :           gfc_finish_decl (tmp);
    2904              : 
    2905              :           /* The presence flag must be boolean.  */
    2906          512 :           gcc_assert (TREE_VALUE (optval_typelist) == boolean_type_node);
    2907          512 :           optval_typelist = TREE_CHAIN (optval_typelist);
    2908              :         }
    2909              : 
    2910              :       /* For non-constant length array arguments, make sure they use
    2911              :          a different type node from TYPE_ARG_TYPES type.  */
    2912       103176 :       if (f->sym->attr.dimension
    2913        22786 :           && type == TREE_VALUE (typelist)
    2914        21474 :           && TREE_CODE (type) == POINTER_TYPE
    2915         9802 :           && GFC_ARRAY_TYPE_P (type)
    2916         7954 :           && f->sym->as->type != AS_ASSUMED_SIZE
    2917       109320 :           && ! COMPLETE_TYPE_P (TREE_TYPE (type)))
    2918              :         {
    2919         2614 :           if (f->sym->attr.flavor == FL_PROCEDURE)
    2920            0 :             type = build_pointer_type (gfc_get_function_type (f->sym));
    2921              :           else
    2922         2614 :             type = gfc_sym_type (f->sym);
    2923              :         }
    2924              : 
    2925       103176 :       if (f->sym->attr.proc_pointer)
    2926          128 :         type = build_pointer_type (type);
    2927              : 
    2928       103176 :       if (f->sym->attr.volatile_)
    2929            3 :         type = build_qualified_type (type, TYPE_QUAL_VOLATILE);
    2930              : 
    2931              :       /* Build the argument declaration. For C descriptors, we use a
    2932              :          '_'-prefixed name for the parm_decl and inside the proc the
    2933              :          sym->name. */
    2934       103176 :       tree parm_name;
    2935       103176 :       if (sym->attr.is_bind_c && is_CFI_desc (f->sym, NULL))
    2936              :         {
    2937         1819 :           strcpy (&name[1], f->sym->name);
    2938         1819 :           name[0] = '_';
    2939         1819 :           parm_name = get_identifier (name);
    2940              :         }
    2941              :       else
    2942       101357 :         parm_name = gfc_sym_identifier (f->sym);
    2943       103176 :       parm = build_decl (input_location, PARM_DECL, parm_name, type);
    2944              : 
    2945       103176 :       if (f->sym->attr.volatile_)
    2946              :         {
    2947            3 :           TREE_THIS_VOLATILE (parm) = 1;
    2948            3 :           TREE_SIDE_EFFECTS (parm) = 1;
    2949              :         }
    2950              : 
    2951              :       /* Fill in arg stuff.  */
    2952       103176 :       DECL_CONTEXT (parm) = fndecl;
    2953       103176 :       DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
    2954              :       /* All implementation args except for VALUE are read-only.  */
    2955       103176 :       if (!f->sym->attr.value)
    2956        94311 :         TREE_READONLY (parm) = 1;
    2957       103176 :       if (POINTER_TYPE_P (type)
    2958        94989 :           && (!f->sym->attr.proc_pointer
    2959        94861 :               && f->sym->attr.flavor != FL_PROCEDURE))
    2960        94085 :         DECL_BY_REFERENCE (parm) = 1;
    2961       103176 :       if (f->sym->attr.optional)
    2962              :         {
    2963         6095 :           gfc_allocate_lang_decl (parm);
    2964         6095 :           GFC_DECL_OPTIONAL_ARGUMENT (parm) = 1;
    2965              :         }
    2966              : 
    2967       103176 :       gfc_finish_decl (parm);
    2968       103176 :       gfc_finish_decl_attrs (parm, &f->sym->attr);
    2969              : 
    2970       103176 :       f->sym->backend_decl = parm;
    2971              : 
    2972              :       /* Coarrays which are descriptorless or assumed-shape pass with
    2973              :          -fcoarray=lib the token and the offset as hidden arguments.  */
    2974       103176 :       if (flag_coarray == GFC_FCOARRAY_LIB
    2975         6899 :           && ((f->sym->ts.type != BT_CLASS && f->sym->attr.codimension
    2976         1526 :                && !f->sym->attr.allocatable)
    2977         5395 :               || (f->sym->ts.type == BT_CLASS
    2978           27 :                   && CLASS_DATA (f->sym)->attr.codimension
    2979           22 :                   && !CLASS_DATA (f->sym)->attr.allocatable)))
    2980              :         {
    2981         1522 :           tree caf_type;
    2982         1522 :           tree token;
    2983         1522 :           tree offset;
    2984              : 
    2985         1522 :           gcc_assert (f->sym->backend_decl != NULL_TREE
    2986              :                       && !sym->attr.is_bind_c);
    2987         1522 :           caf_type = f->sym->ts.type == BT_CLASS
    2988         1522 :                      ? TREE_TYPE (CLASS_DATA (f->sym)->backend_decl)
    2989         1504 :                      : TREE_TYPE (f->sym->backend_decl);
    2990              : 
    2991         1522 :           token = build_decl (input_location, PARM_DECL,
    2992              :                               create_tmp_var_name ("caf_token"),
    2993              :                               build_qualified_type (pvoid_type_node,
    2994              :                                                     TYPE_QUAL_RESTRICT));
    2995         1522 :           if ((f->sym->ts.type != BT_CLASS
    2996         1504 :                && f->sym->as->type != AS_DEFERRED)
    2997           18 :               || (f->sym->ts.type == BT_CLASS
    2998           18 :                   && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
    2999              :             {
    3000         1522 :               gcc_assert (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL
    3001              :                           || GFC_DECL_TOKEN (f->sym->backend_decl) == NULL_TREE);
    3002         1522 :               if (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL)
    3003         1517 :                 gfc_allocate_lang_decl (f->sym->backend_decl);
    3004         1522 :               GFC_DECL_TOKEN (f->sym->backend_decl) = token;
    3005              :             }
    3006              :           else
    3007              :             {
    3008            0 :               gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) == NULL_TREE);
    3009            0 :               GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) = token;
    3010              :             }
    3011              : 
    3012         1522 :           DECL_CONTEXT (token) = fndecl;
    3013         1522 :           DECL_ARTIFICIAL (token) = 1;
    3014         1522 :           DECL_ARG_TYPE (token) = TREE_VALUE (typelist);
    3015         1522 :           TREE_READONLY (token) = 1;
    3016         1522 :           hidden_arglist = chainon (hidden_arglist, token);
    3017         1522 :           hidden_typelist = TREE_CHAIN (hidden_typelist);
    3018         1522 :           gfc_finish_decl (token);
    3019              : 
    3020         1522 :           offset = build_decl (input_location, PARM_DECL,
    3021              :                                create_tmp_var_name ("caf_offset"),
    3022              :                                gfc_array_index_type);
    3023              : 
    3024         1522 :           if ((f->sym->ts.type != BT_CLASS
    3025         1504 :                && f->sym->as->type != AS_DEFERRED)
    3026           18 :               || (f->sym->ts.type == BT_CLASS
    3027           18 :                   && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
    3028              :             {
    3029         1522 :               gcc_assert (GFC_DECL_CAF_OFFSET (f->sym->backend_decl)
    3030              :                                                == NULL_TREE);
    3031         1522 :               GFC_DECL_CAF_OFFSET (f->sym->backend_decl) = offset;
    3032              :             }
    3033              :           else
    3034              :             {
    3035            0 :               gcc_assert (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) == NULL_TREE);
    3036            0 :               GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) = offset;
    3037              :             }
    3038         1522 :           DECL_CONTEXT (offset) = fndecl;
    3039         1522 :           DECL_ARTIFICIAL (offset) = 1;
    3040         1522 :           DECL_ARG_TYPE (offset) = TREE_VALUE (typelist);
    3041         1522 :           TREE_READONLY (offset) = 1;
    3042         1522 :           hidden_arglist = chainon (hidden_arglist, offset);
    3043         1522 :           hidden_typelist = TREE_CHAIN (hidden_typelist);
    3044         1522 :           gfc_finish_decl (offset);
    3045              :         }
    3046              : 
    3047       103176 :       arglist = chainon (arglist, parm);
    3048       103176 :       typelist = TREE_CHAIN (typelist);
    3049              :     }
    3050              : 
    3051              :   /* Add hidden present status for optional+value arguments.  */
    3052        87468 :   arglist = chainon (arglist, optval_arglist);
    3053              : 
    3054              :   /* Add the hidden string length parameters, unless the procedure
    3055              :      is bind(C).  */
    3056        87468 :   if (!sym->attr.is_bind_c)
    3057        85350 :     arglist = chainon (arglist, hidden_arglist);
    3058              : 
    3059       174936 :   gcc_assert (hidden_typelist == NULL_TREE
    3060              :               || TREE_VALUE (hidden_typelist) == void_type_node);
    3061        87468 :   DECL_ARGUMENTS (fndecl) = arglist;
    3062        87468 : }
    3063              : 
    3064              : /* Do the setup necessary before generating the body of a function.  */
    3065              : 
    3066              : static void
    3067        85656 : trans_function_start (gfc_symbol * sym)
    3068              : {
    3069        85656 :   tree fndecl;
    3070              : 
    3071        85656 :   fndecl = sym->backend_decl;
    3072              : 
    3073              :   /* Let GCC know the current scope is this function.  */
    3074        85656 :   current_function_decl = fndecl;
    3075              : 
    3076              :   /* Let the world know what we're about to do.  */
    3077        85656 :   announce_function (fndecl);
    3078              : 
    3079        85656 :   if (DECL_FILE_SCOPE_P (fndecl))
    3080              :     {
    3081              :       /* Create RTL for function declaration.  */
    3082        37290 :       rest_of_decl_compilation (fndecl, 1, 0);
    3083              :     }
    3084              : 
    3085              :   /* Create RTL for function definition.  */
    3086        85656 :   make_decl_rtl (fndecl);
    3087              : 
    3088        85656 :   allocate_struct_function (fndecl, false);
    3089              : 
    3090              :   /* function.cc requires a push at the start of the function.  */
    3091        85656 :   pushlevel ();
    3092        85656 : }
    3093              : 
    3094              : /* Create thunks for alternate entry points.  */
    3095              : 
    3096              : static void
    3097          634 : build_entry_thunks (gfc_namespace * ns, bool global)
    3098              : {
    3099          634 :   gfc_formal_arglist *formal;
    3100          634 :   gfc_formal_arglist *thunk_formal;
    3101          634 :   gfc_entry_list *el;
    3102          634 :   gfc_symbol *thunk_sym;
    3103          634 :   stmtblock_t body;
    3104          634 :   tree thunk_fndecl;
    3105          634 :   tree tmp;
    3106          634 :   location_t old_loc;
    3107              : 
    3108              :   /* This should always be a toplevel function.  */
    3109          634 :   gcc_assert (current_function_decl == NULL_TREE);
    3110              : 
    3111          634 :   old_loc = input_location;
    3112         1979 :   for (el = ns->entries; el; el = el->next)
    3113              :     {
    3114         1345 :       vec<tree, va_gc> *args = NULL;
    3115         1345 :       vec<tree, va_gc> *string_args = NULL;
    3116              : 
    3117         1345 :       thunk_sym = el->sym;
    3118              : 
    3119         1345 :       build_function_decl (thunk_sym, global);
    3120         1345 :       create_function_arglist (thunk_sym);
    3121              : 
    3122         1345 :       trans_function_start (thunk_sym);
    3123              : 
    3124         1345 :       thunk_fndecl = thunk_sym->backend_decl;
    3125              : 
    3126         1345 :       gfc_init_block (&body);
    3127              : 
    3128              :       /* Pass extra parameter identifying this entry point.  */
    3129         1345 :       tmp = build_int_cst (gfc_array_index_type, el->id);
    3130         1345 :       vec_safe_push (args, tmp);
    3131              : 
    3132         1345 :       if (thunk_sym->attr.function)
    3133              :         {
    3134         1134 :           if (gfc_return_by_reference (ns->proc_name))
    3135              :             {
    3136          252 :               tree ref = DECL_ARGUMENTS (current_function_decl);
    3137          252 :               vec_safe_push (args, ref);
    3138          252 :               if (ns->proc_name->ts.type == BT_CHARACTER)
    3139          136 :                 vec_safe_push (args, DECL_CHAIN (ref));
    3140              :             }
    3141              :         }
    3142              : 
    3143         2893 :       for (formal = gfc_sym_get_dummy_args (ns->proc_name); formal;
    3144         1548 :            formal = formal->next)
    3145              :         {
    3146              :           /* Ignore alternate returns.  */
    3147         1548 :           if (formal->sym == NULL)
    3148           36 :             continue;
    3149              : 
    3150              :           /* We don't have a clever way of identifying arguments, so resort to
    3151              :              a brute-force search.  */
    3152         1512 :           for (thunk_formal = gfc_sym_get_dummy_args (thunk_sym);
    3153         2667 :                thunk_formal;
    3154         1155 :                thunk_formal = thunk_formal->next)
    3155              :             {
    3156         2236 :               if (thunk_formal->sym == formal->sym)
    3157              :                 break;
    3158              :             }
    3159              : 
    3160         1512 :           if (thunk_formal)
    3161              :             {
    3162              :               /* Pass the argument.  */
    3163         1081 :               DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1;
    3164         1081 :               vec_safe_push (args, thunk_formal->sym->backend_decl);
    3165         1081 :               if (formal->sym->ts.type == BT_CHARACTER)
    3166              :                 {
    3167           94 :                   tmp = thunk_formal->sym->ts.u.cl->backend_decl;
    3168           94 :                   vec_safe_push (string_args, tmp);
    3169              :                 }
    3170              :             }
    3171              :           else
    3172              :             {
    3173              :               /* Pass NULL for a missing argument.  */
    3174          431 :               vec_safe_push (args, null_pointer_node);
    3175          431 :               if (formal->sym->ts.type == BT_CHARACTER)
    3176              :                 {
    3177           38 :                   tmp = build_int_cst (gfc_charlen_type_node, 0);
    3178           38 :                   vec_safe_push (string_args, tmp);
    3179              :                 }
    3180              :             }
    3181              :         }
    3182              : 
    3183              :       /* Call the master function.  */
    3184         1345 :       vec_safe_splice (args, string_args);
    3185         1345 :       tmp = ns->proc_name->backend_decl;
    3186         1345 :       tmp = build_call_expr_loc_vec (input_location, tmp, args);
    3187         1345 :       if (ns->proc_name->attr.mixed_entry_master)
    3188              :         {
    3189          214 :           tree union_decl, field;
    3190          214 :           tree master_type = TREE_TYPE (ns->proc_name->backend_decl);
    3191              : 
    3192          214 :           union_decl = build_decl (input_location,
    3193              :                                    VAR_DECL, get_identifier ("__result"),
    3194          214 :                                    TREE_TYPE (master_type));
    3195          214 :           DECL_ARTIFICIAL (union_decl) = 1;
    3196          214 :           DECL_EXTERNAL (union_decl) = 0;
    3197          214 :           TREE_PUBLIC (union_decl) = 0;
    3198          214 :           TREE_USED (union_decl) = 1;
    3199          214 :           layout_decl (union_decl, 0);
    3200          214 :           pushdecl (union_decl);
    3201              : 
    3202          214 :           DECL_CONTEXT (union_decl) = current_function_decl;
    3203          214 :           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    3204          214 :                                  TREE_TYPE (union_decl), union_decl, tmp);
    3205          214 :           gfc_add_expr_to_block (&body, tmp);
    3206              : 
    3207          214 :           for (field = TYPE_FIELDS (TREE_TYPE (union_decl));
    3208          348 :                field; field = DECL_CHAIN (field))
    3209          348 :             if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
    3210          348 :                 thunk_sym->result->name) == 0)
    3211              :               break;
    3212            0 :           gcc_assert (field != NULL_TREE);
    3213          214 :           tmp = fold_build3_loc (input_location, COMPONENT_REF,
    3214          214 :                                  TREE_TYPE (field), union_decl, field,
    3215              :                                  NULL_TREE);
    3216          214 :           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    3217          214 :                              TREE_TYPE (DECL_RESULT (current_function_decl)),
    3218          214 :                              DECL_RESULT (current_function_decl), tmp);
    3219          214 :           tmp = build1_v (RETURN_EXPR, tmp);
    3220              :         }
    3221         1131 :       else if (TREE_TYPE (DECL_RESULT (current_function_decl))
    3222         1131 :                != void_type_node)
    3223              :         {
    3224          693 :           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    3225          693 :                              TREE_TYPE (DECL_RESULT (current_function_decl)),
    3226          693 :                              DECL_RESULT (current_function_decl), tmp);
    3227          693 :           tmp = build1_v (RETURN_EXPR, tmp);
    3228              :         }
    3229         1345 :       gfc_add_expr_to_block (&body, tmp);
    3230              : 
    3231              :       /* Finish off this function and send it for code generation.  */
    3232         1345 :       DECL_SAVED_TREE (thunk_fndecl) = gfc_finish_block (&body);
    3233         1345 :       tmp = getdecls ();
    3234         1345 :       poplevel (1, 1);
    3235         1345 :       BLOCK_SUPERCONTEXT (DECL_INITIAL (thunk_fndecl)) = thunk_fndecl;
    3236         2690 :       DECL_SAVED_TREE (thunk_fndecl)
    3237         2690 :         = fold_build3_loc (DECL_SOURCE_LOCATION (thunk_fndecl), BIND_EXPR,
    3238         1345 :                            void_type_node, tmp, DECL_SAVED_TREE (thunk_fndecl),
    3239         1345 :                            DECL_INITIAL (thunk_fndecl));
    3240              : 
    3241              :       /* Output the GENERIC tree.  */
    3242         1345 :       dump_function (TDI_original, thunk_fndecl);
    3243              : 
    3244              :       /* Store the end of the function, so that we get good line number
    3245              :          info for the epilogue.  */
    3246         1345 :       cfun->function_end_locus = input_location;
    3247              : 
    3248              :       /* We're leaving the context of this function, so zap cfun.
    3249              :          It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
    3250              :          tree_rest_of_compilation.  */
    3251         1345 :       set_cfun (NULL);
    3252              : 
    3253         1345 :       current_function_decl = NULL_TREE;
    3254              : 
    3255         1345 :       cgraph_node::finalize_function (thunk_fndecl, true);
    3256              : 
    3257              :       /* We share the symbols in the formal argument list with other entry
    3258              :          points and the master function.  Clear them so that they are
    3259              :          recreated for each function.  */
    3260         2471 :       for (formal = gfc_sym_get_dummy_args (thunk_sym); formal;
    3261         1126 :            formal = formal->next)
    3262         1126 :         if (formal->sym != NULL)  /* Ignore alternate returns.  */
    3263              :           {
    3264         1081 :             formal->sym->backend_decl = NULL_TREE;
    3265         1081 :             if (formal->sym->ts.type == BT_CHARACTER)
    3266           94 :               formal->sym->ts.u.cl->backend_decl = NULL_TREE;
    3267              :           }
    3268              : 
    3269         1345 :       if (thunk_sym->attr.function)
    3270              :         {
    3271         1134 :           if (thunk_sym->ts.type == BT_CHARACTER)
    3272          138 :             thunk_sym->ts.u.cl->backend_decl = NULL_TREE;
    3273         1134 :           if (thunk_sym->result->ts.type == BT_CHARACTER)
    3274          138 :             thunk_sym->result->ts.u.cl->backend_decl = NULL_TREE;
    3275              :         }
    3276              :     }
    3277              : 
    3278          634 :   input_location = old_loc;
    3279          634 : }
    3280              : 
    3281              : 
    3282              : /* Create a decl for a function, and create any thunks for alternate entry
    3283              :    points. If global is true, generate the function in the global binding
    3284              :    level, otherwise in the current binding level (which can be global).  */
    3285              : 
    3286              : void
    3287        84311 : gfc_create_function_decl (gfc_namespace * ns, bool global)
    3288              : {
    3289              :   /* Create a declaration for the master function.  */
    3290        84311 :   build_function_decl (ns->proc_name, global);
    3291              : 
    3292              :   /* Compile the entry thunks.  */
    3293        84311 :   if (ns->entries)
    3294          634 :     build_entry_thunks (ns, global);
    3295              : 
    3296              :   /* Now create the read argument list.  */
    3297        84311 :   create_function_arglist (ns->proc_name);
    3298              : 
    3299        84311 :   if (ns->omp_declare_simd)
    3300           94 :     gfc_trans_omp_declare_simd (ns);
    3301              : 
    3302              :   /* Handle 'declare variant' directives.  The applicable directives might
    3303              :      be declared in a parent namespace, so this needs to be called even if
    3304              :      there are no local directives.  */
    3305        84311 :   if (flag_openmp)
    3306         8653 :     gfc_trans_omp_declare_variant (ns, NULL);
    3307        84311 : }
    3308              : 
    3309              : /* Return the decl used to hold the function return value.  If
    3310              :    parent_flag is set, the context is the parent_scope.  */
    3311              : 
    3312              : tree
    3313        12791 : gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
    3314              : {
    3315        12791 :   tree decl;
    3316        12791 :   tree length;
    3317        12791 :   tree this_fake_result_decl;
    3318        12791 :   tree this_function_decl;
    3319              : 
    3320        12791 :   char name[GFC_MAX_SYMBOL_LEN + 10];
    3321              : 
    3322        12791 :   if (parent_flag)
    3323              :     {
    3324          167 :       this_fake_result_decl = parent_fake_result_decl;
    3325          167 :       this_function_decl = DECL_CONTEXT (current_function_decl);
    3326              :     }
    3327              :   else
    3328              :     {
    3329        12624 :       this_fake_result_decl = current_fake_result_decl;
    3330        12624 :       this_function_decl = current_function_decl;
    3331              :     }
    3332              : 
    3333        12791 :   if (sym
    3334        12741 :       && sym->ns->proc_name->backend_decl == this_function_decl
    3335         4743 :       && sym->ns->proc_name->attr.entry_master
    3336         2272 :       && sym != sym->ns->proc_name)
    3337              :     {
    3338         1420 :       tree t = NULL, var;
    3339         1420 :       if (this_fake_result_decl != NULL)
    3340         1392 :         for (t = TREE_CHAIN (this_fake_result_decl); t; t = TREE_CHAIN (t))
    3341         1041 :           if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), sym->name) == 0)
    3342              :             break;
    3343          928 :       if (t)
    3344          577 :         return TREE_VALUE (t);
    3345          843 :       decl = gfc_get_fake_result_decl (sym->ns->proc_name, parent_flag);
    3346              : 
    3347          843 :       if (parent_flag)
    3348           14 :         this_fake_result_decl = parent_fake_result_decl;
    3349              :       else
    3350          829 :         this_fake_result_decl = current_fake_result_decl;
    3351              : 
    3352          843 :       if (decl && sym->ns->proc_name->attr.mixed_entry_master)
    3353              :         {
    3354          214 :           tree field;
    3355              : 
    3356          214 :           for (field = TYPE_FIELDS (TREE_TYPE (decl));
    3357          348 :                field; field = DECL_CHAIN (field))
    3358          348 :             if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
    3359              :                 sym->name) == 0)
    3360              :               break;
    3361              : 
    3362          214 :           gcc_assert (field != NULL_TREE);
    3363          214 :           decl = fold_build3_loc (input_location, COMPONENT_REF,
    3364          214 :                                   TREE_TYPE (field), decl, field, NULL_TREE);
    3365              :         }
    3366              : 
    3367          843 :       var = create_tmp_var_raw (TREE_TYPE (decl), sym->name);
    3368          843 :       if (parent_flag)
    3369           14 :         gfc_add_decl_to_parent_function (var);
    3370              :       else
    3371          829 :         gfc_add_decl_to_function (var);
    3372              : 
    3373          843 :       SET_DECL_VALUE_EXPR (var, decl);
    3374          843 :       DECL_HAS_VALUE_EXPR_P (var) = 1;
    3375          843 :       GFC_DECL_RESULT (var) = 1;
    3376              : 
    3377          843 :       TREE_CHAIN (this_fake_result_decl)
    3378          843 :           = tree_cons (get_identifier (sym->name), var,
    3379          843 :                        TREE_CHAIN (this_fake_result_decl));
    3380          843 :       return var;
    3381              :     }
    3382              : 
    3383        11371 :   if (this_fake_result_decl != NULL_TREE)
    3384         3966 :     return TREE_VALUE (this_fake_result_decl);
    3385              : 
    3386              :   /* Only when gfc_get_fake_result_decl is called by gfc_trans_return,
    3387              :      sym is NULL.  */
    3388         7405 :   if (!sym)
    3389              :     return NULL_TREE;
    3390              : 
    3391         7405 :   if (sym->ts.type == BT_CHARACTER)
    3392              :     {
    3393          821 :       if (sym->ts.u.cl->backend_decl == NULL_TREE)
    3394            0 :         length = gfc_create_string_length (sym);
    3395              :       else
    3396              :         length = sym->ts.u.cl->backend_decl;
    3397          821 :       if (VAR_P (length) && DECL_CONTEXT (length) == NULL_TREE)
    3398          490 :         gfc_add_decl_to_function (length);
    3399              :     }
    3400              : 
    3401         7405 :   if (gfc_return_by_reference (sym))
    3402              :     {
    3403         1582 :       decl = DECL_ARGUMENTS (this_function_decl);
    3404              : 
    3405         1582 :       if (sym->ns->proc_name->backend_decl == this_function_decl
    3406          381 :           && sym->ns->proc_name->attr.entry_master)
    3407           61 :         decl = DECL_CHAIN (decl);
    3408              : 
    3409         1582 :       TREE_USED (decl) = 1;
    3410         1582 :       if (sym->as)
    3411          807 :         decl = gfc_build_dummy_array_decl (sym, decl);
    3412              :     }
    3413              :   else
    3414              :     {
    3415        11646 :       sprintf (name, "__result_%.20s",
    3416         5823 :                IDENTIFIER_POINTER (DECL_NAME (this_function_decl)));
    3417              : 
    3418         5823 :       if (!sym->attr.mixed_entry_master && sym->attr.function)
    3419         5682 :         decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
    3420              :                            VAR_DECL, get_identifier (name),
    3421              :                            gfc_sym_type (sym));
    3422              :       else
    3423          141 :         decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
    3424              :                            VAR_DECL, get_identifier (name),
    3425          141 :                            TREE_TYPE (TREE_TYPE (this_function_decl)));
    3426         5823 :       DECL_ARTIFICIAL (decl) = 1;
    3427         5823 :       DECL_EXTERNAL (decl) = 0;
    3428         5823 :       TREE_PUBLIC (decl) = 0;
    3429         5823 :       TREE_USED (decl) = 1;
    3430         5823 :       GFC_DECL_RESULT (decl) = 1;
    3431         5823 :       TREE_ADDRESSABLE (decl) = 1;
    3432              : 
    3433         5823 :       layout_decl (decl, 0);
    3434         5823 :       gfc_finish_decl_attrs (decl, &sym->attr);
    3435              : 
    3436         5823 :       if (parent_flag)
    3437           27 :         gfc_add_decl_to_parent_function (decl);
    3438              :       else
    3439         5796 :         gfc_add_decl_to_function (decl);
    3440              :     }
    3441              : 
    3442         7405 :   if (parent_flag)
    3443           39 :     parent_fake_result_decl = build_tree_list (NULL, decl);
    3444              :   else
    3445         7366 :     current_fake_result_decl = build_tree_list (NULL, decl);
    3446              : 
    3447         7405 :   if (sym->attr.assign)
    3448            1 :     DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl);
    3449              : 
    3450              :   return decl;
    3451              : }
    3452              : 
    3453              : 
    3454              : /* Builds a function decl.  The remaining parameters are the types of the
    3455              :    function arguments.  Negative nargs indicates a varargs function.  */
    3456              : 
    3457              : static tree
    3458      4706256 : build_library_function_decl_1 (tree name, const char *spec,
    3459              :                                tree rettype, int nargs, va_list p)
    3460              : {
    3461      4706256 :   vec<tree, va_gc> *arglist;
    3462      4706256 :   tree fntype;
    3463      4706256 :   tree fndecl;
    3464      4706256 :   int n;
    3465              : 
    3466              :   /* Library functions must be declared with global scope.  */
    3467      4706256 :   gcc_assert (current_function_decl == NULL_TREE);
    3468              : 
    3469              :   /* Create a list of the argument types.  */
    3470      4706256 :   vec_alloc (arglist, abs (nargs));
    3471     18722070 :   for (n = abs (nargs); n > 0; n--)
    3472              :     {
    3473     14015814 :       tree argtype = va_arg (p, tree);
    3474     14015814 :       arglist->quick_push (argtype);
    3475              :     }
    3476              : 
    3477              :   /* Build the function type and decl.  */
    3478      4706256 :   if (nargs >= 0)
    3479     13488776 :     fntype = build_function_type_vec (rettype, arglist);
    3480              :   else
    3481       564498 :     fntype = build_varargs_function_type_vec (rettype, arglist);
    3482      4706256 :   if (spec)
    3483              :     {
    3484      2746425 :       tree attr_args = build_tree_list (NULL_TREE,
    3485      2746425 :                                         build_string (strlen (spec), spec));
    3486      2746425 :       tree attrs = tree_cons (get_identifier ("fn spec"),
    3487      2746425 :                               attr_args, TYPE_ATTRIBUTES (fntype));
    3488      2746425 :       fntype = build_type_attribute_variant (fntype, attrs);
    3489              :     }
    3490      4706256 :   fndecl = build_decl (input_location,
    3491              :                        FUNCTION_DECL, name, fntype);
    3492              : 
    3493              :   /* Mark this decl as external.  */
    3494      4706256 :   DECL_EXTERNAL (fndecl) = 1;
    3495      4706256 :   TREE_PUBLIC (fndecl) = 1;
    3496              : 
    3497      4706256 :   pushdecl (fndecl);
    3498              : 
    3499      4706256 :   rest_of_decl_compilation (fndecl, 1, 0);
    3500              : 
    3501      4706256 :   return fndecl;
    3502              : }
    3503              : 
    3504              : /* Builds a function decl.  The remaining parameters are the types of the
    3505              :    function arguments.  Negative nargs indicates a varargs function.  */
    3506              : 
    3507              : tree
    3508      1959831 : gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
    3509              : {
    3510      1959831 :   tree ret;
    3511      1959831 :   va_list args;
    3512      1959831 :   va_start (args, nargs);
    3513      1959831 :   ret = build_library_function_decl_1 (name, NULL, rettype, nargs, args);
    3514      1959831 :   va_end (args);
    3515      1959831 :   return ret;
    3516              : }
    3517              : 
    3518              : /* Builds a function decl.  The remaining parameters are the types of the
    3519              :    function arguments.  Negative nargs indicates a varargs function.
    3520              :    The SPEC parameter specifies the function argument and return type
    3521              :    specification according to the fnspec function type attribute.  */
    3522              : 
    3523              : tree
    3524      2746425 : gfc_build_library_function_decl_with_spec (tree name, const char *spec,
    3525              :                                            tree rettype, int nargs, ...)
    3526              : {
    3527      2746425 :   tree ret;
    3528      2746425 :   va_list args;
    3529      2746425 :   va_start (args, nargs);
    3530      2746425 :   if (flag_checking)
    3531              :     {
    3532      2746425 :       attr_fnspec fnspec (spec, strlen (spec));
    3533      2746425 :       fnspec.verify ();
    3534              :     }
    3535      2746425 :   ret = build_library_function_decl_1 (name, spec, rettype, nargs, args);
    3536      2746425 :   va_end (args);
    3537      2746425 :   return ret;
    3538              : }
    3539              : 
    3540              : static void
    3541        31361 : gfc_build_intrinsic_function_decls (void)
    3542              : {
    3543        31361 :   tree gfc_int4_type_node = gfc_get_int_type (4);
    3544        31361 :   tree gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
    3545        31361 :   tree gfc_int8_type_node = gfc_get_int_type (8);
    3546        31361 :   tree gfc_pint8_type_node = build_pointer_type (gfc_int8_type_node);
    3547        31361 :   tree gfc_int16_type_node = gfc_get_int_type (16);
    3548        31361 :   tree gfc_logical4_type_node = gfc_get_logical_type (4);
    3549        31361 :   tree pchar1_type_node = gfc_get_pchar_type (1);
    3550        31361 :   tree pchar4_type_node = gfc_get_pchar_type (4);
    3551              : 
    3552              :   /* String functions.  */
    3553        31361 :   gfor_fndecl_compare_string = gfc_build_library_function_decl_with_spec (
    3554              :         get_identifier (PREFIX("compare_string")), ". . R . R ",
    3555              :         integer_type_node, 4, gfc_charlen_type_node, pchar1_type_node,
    3556              :         gfc_charlen_type_node, pchar1_type_node);
    3557        31361 :   DECL_PURE_P (gfor_fndecl_compare_string) = 1;
    3558        31361 :   TREE_NOTHROW (gfor_fndecl_compare_string) = 1;
    3559              : 
    3560        31361 :   gfor_fndecl_concat_string = gfc_build_library_function_decl_with_spec (
    3561              :         get_identifier (PREFIX("concat_string")), ". . W . R . R ",
    3562              :         void_type_node, 6, gfc_charlen_type_node, pchar1_type_node,
    3563              :         gfc_charlen_type_node, pchar1_type_node,
    3564              :         gfc_charlen_type_node, pchar1_type_node);
    3565        31361 :   TREE_NOTHROW (gfor_fndecl_concat_string) = 1;
    3566              : 
    3567        31361 :   gfor_fndecl_string_len_trim = gfc_build_library_function_decl_with_spec (
    3568              :         get_identifier (PREFIX("string_len_trim")), ". . R ",
    3569              :         gfc_charlen_type_node, 2, gfc_charlen_type_node, pchar1_type_node);
    3570        31361 :   DECL_PURE_P (gfor_fndecl_string_len_trim) = 1;
    3571        31361 :   TREE_NOTHROW (gfor_fndecl_string_len_trim) = 1;
    3572              : 
    3573        31361 :   gfor_fndecl_string_index = gfc_build_library_function_decl_with_spec (
    3574              :         get_identifier (PREFIX("string_index")), ". . R . R . ",
    3575              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
    3576              :         gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
    3577        31361 :   DECL_PURE_P (gfor_fndecl_string_index) = 1;
    3578        31361 :   TREE_NOTHROW (gfor_fndecl_string_index) = 1;
    3579              : 
    3580        31361 :   gfor_fndecl_string_scan = gfc_build_library_function_decl_with_spec (
    3581              :         get_identifier (PREFIX("string_scan")), ". . R . R . ",
    3582              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
    3583              :         gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
    3584        31361 :   DECL_PURE_P (gfor_fndecl_string_scan) = 1;
    3585        31361 :   TREE_NOTHROW (gfor_fndecl_string_scan) = 1;
    3586              : 
    3587        31361 :   gfor_fndecl_string_verify = gfc_build_library_function_decl_with_spec (
    3588              :         get_identifier (PREFIX("string_verify")), ". . R . R . ",
    3589              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
    3590              :         gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
    3591        31361 :   DECL_PURE_P (gfor_fndecl_string_verify) = 1;
    3592        31361 :   TREE_NOTHROW (gfor_fndecl_string_verify) = 1;
    3593              : 
    3594        31361 :   gfor_fndecl_string_trim = gfc_build_library_function_decl_with_spec (
    3595              :         get_identifier (PREFIX("string_trim")), ". W w . R ",
    3596              :         void_type_node, 4, build_pointer_type (gfc_charlen_type_node),
    3597              :         build_pointer_type (pchar1_type_node), gfc_charlen_type_node,
    3598              :         pchar1_type_node);
    3599              : 
    3600        31361 :   gfor_fndecl_string_minmax = gfc_build_library_function_decl_with_spec (
    3601              :         get_identifier (PREFIX("string_minmax")), ". W w . R ",
    3602              :         void_type_node, -4, build_pointer_type (gfc_charlen_type_node),
    3603              :         build_pointer_type (pchar1_type_node), integer_type_node,
    3604              :         integer_type_node);
    3605              : 
    3606        31361 :   gfor_fndecl_string_split = gfc_build_library_function_decl_with_spec (
    3607              :     get_identifier (PREFIX ("string_split")), ". . R . R . . ",
    3608              :     gfc_charlen_type_node, 6, gfc_charlen_type_node, pchar1_type_node,
    3609              :     gfc_charlen_type_node, pchar1_type_node, gfc_charlen_type_node,
    3610              :     gfc_logical4_type_node);
    3611              : 
    3612        31361 :   {
    3613        31361 :     tree copy_helper_ptr_type;
    3614        31361 :     tree copy_helper_fn_type;
    3615              : 
    3616        31361 :     copy_helper_fn_type = build_function_type_list (void_type_node,
    3617              :                                                     pvoid_type_node,
    3618              :                                                     pvoid_type_node,
    3619              :                                                     NULL_TREE);
    3620        31361 :     copy_helper_ptr_type = build_pointer_type (copy_helper_fn_type);
    3621              : 
    3622        31361 :     gfor_fndecl_cfi_deep_copy_array
    3623        31361 :       = gfc_build_library_function_decl_with_spec (
    3624              :           get_identifier (PREFIX ("cfi_deep_copy_array")), ". R R . ",
    3625              :           void_type_node, 3, pvoid_type_node, pvoid_type_node,
    3626              :           copy_helper_ptr_type);
    3627              :   }
    3628              : 
    3629        31361 :   gfor_fndecl_adjustl = gfc_build_library_function_decl_with_spec (
    3630              :         get_identifier (PREFIX("adjustl")), ". W . R ",
    3631              :         void_type_node, 3, pchar1_type_node, gfc_charlen_type_node,
    3632              :         pchar1_type_node);
    3633        31361 :   TREE_NOTHROW (gfor_fndecl_adjustl) = 1;
    3634              : 
    3635        31361 :   gfor_fndecl_adjustr = gfc_build_library_function_decl_with_spec (
    3636              :         get_identifier (PREFIX("adjustr")), ". W . R ",
    3637              :         void_type_node, 3, pchar1_type_node, gfc_charlen_type_node,
    3638              :         pchar1_type_node);
    3639        31361 :   TREE_NOTHROW (gfor_fndecl_adjustr) = 1;
    3640              : 
    3641        31361 :   gfor_fndecl_select_string =  gfc_build_library_function_decl_with_spec (
    3642              :         get_identifier (PREFIX("select_string")), ". R . R . ",
    3643              :         integer_type_node, 4, pvoid_type_node, integer_type_node,
    3644              :         pchar1_type_node, gfc_charlen_type_node);
    3645        31361 :   DECL_PURE_P (gfor_fndecl_select_string) = 1;
    3646        31361 :   TREE_NOTHROW (gfor_fndecl_select_string) = 1;
    3647              : 
    3648        31361 :   gfor_fndecl_compare_string_char4 = gfc_build_library_function_decl_with_spec (
    3649              :         get_identifier (PREFIX("compare_string_char4")), ". . R . R ",
    3650              :         integer_type_node, 4, gfc_charlen_type_node, pchar4_type_node,
    3651              :         gfc_charlen_type_node, pchar4_type_node);
    3652        31361 :   DECL_PURE_P (gfor_fndecl_compare_string_char4) = 1;
    3653        31361 :   TREE_NOTHROW (gfor_fndecl_compare_string_char4) = 1;
    3654              : 
    3655        31361 :   gfor_fndecl_concat_string_char4 = gfc_build_library_function_decl_with_spec (
    3656              :         get_identifier (PREFIX("concat_string_char4")), ". . W . R . R ",
    3657              :         void_type_node, 6, gfc_charlen_type_node, pchar4_type_node,
    3658              :         gfc_charlen_type_node, pchar4_type_node, gfc_charlen_type_node,
    3659              :         pchar4_type_node);
    3660        31361 :   TREE_NOTHROW (gfor_fndecl_concat_string_char4) = 1;
    3661              : 
    3662        31361 :   gfor_fndecl_string_len_trim_char4 = gfc_build_library_function_decl_with_spec (
    3663              :         get_identifier (PREFIX("string_len_trim_char4")), ". . R ",
    3664              :         gfc_charlen_type_node, 2, gfc_charlen_type_node, pchar4_type_node);
    3665        31361 :   DECL_PURE_P (gfor_fndecl_string_len_trim_char4) = 1;
    3666        31361 :   TREE_NOTHROW (gfor_fndecl_string_len_trim_char4) = 1;
    3667              : 
    3668        31361 :   gfor_fndecl_string_index_char4 = gfc_build_library_function_decl_with_spec (
    3669              :         get_identifier (PREFIX("string_index_char4")), ". . R . R . ",
    3670              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
    3671              :         gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
    3672        31361 :   DECL_PURE_P (gfor_fndecl_string_index_char4) = 1;
    3673        31361 :   TREE_NOTHROW (gfor_fndecl_string_index_char4) = 1;
    3674              : 
    3675        31361 :   gfor_fndecl_string_scan_char4 = gfc_build_library_function_decl_with_spec (
    3676              :         get_identifier (PREFIX("string_scan_char4")), ". . R . R . ",
    3677              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
    3678              :         gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
    3679        31361 :   DECL_PURE_P (gfor_fndecl_string_scan_char4) = 1;
    3680        31361 :   TREE_NOTHROW (gfor_fndecl_string_scan_char4) = 1;
    3681              : 
    3682        31361 :   gfor_fndecl_string_verify_char4 = gfc_build_library_function_decl_with_spec (
    3683              :         get_identifier (PREFIX("string_verify_char4")), ". . R . R . ",
    3684              :         gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
    3685              :         gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
    3686        31361 :   DECL_PURE_P (gfor_fndecl_string_verify_char4) = 1;
    3687        31361 :   TREE_NOTHROW (gfor_fndecl_string_verify_char4) = 1;
    3688              : 
    3689        31361 :   gfor_fndecl_string_trim_char4 = gfc_build_library_function_decl_with_spec (
    3690              :         get_identifier (PREFIX("string_trim_char4")), ". W w . R ",
    3691              :         void_type_node, 4, build_pointer_type (gfc_charlen_type_node),
    3692              :         build_pointer_type (pchar4_type_node), gfc_charlen_type_node,
    3693              :         pchar4_type_node);
    3694              : 
    3695        31361 :   gfor_fndecl_string_minmax_char4 = gfc_build_library_function_decl_with_spec (
    3696              :         get_identifier (PREFIX("string_minmax_char4")), ". W w . R ",
    3697              :         void_type_node, -4, build_pointer_type (gfc_charlen_type_node),
    3698              :         build_pointer_type (pchar4_type_node), integer_type_node,
    3699              :         integer_type_node);
    3700              : 
    3701        31361 :   gfor_fndecl_string_split_char4 = gfc_build_library_function_decl_with_spec (
    3702              :     get_identifier (PREFIX ("string_split_char4")), ". . R . R . . ",
    3703              :     gfc_charlen_type_node, 6, gfc_charlen_type_node, pchar4_type_node,
    3704              :     gfc_charlen_type_node, pchar4_type_node, gfc_charlen_type_node,
    3705              :     gfc_logical4_type_node);
    3706              : 
    3707        31361 :   gfor_fndecl_adjustl_char4 = gfc_build_library_function_decl_with_spec (
    3708              :         get_identifier (PREFIX("adjustl_char4")), ". W . R ",
    3709              :         void_type_node, 3, pchar4_type_node, gfc_charlen_type_node,
    3710              :         pchar4_type_node);
    3711        31361 :   TREE_NOTHROW (gfor_fndecl_adjustl_char4) = 1;
    3712              : 
    3713        31361 :   gfor_fndecl_adjustr_char4 = gfc_build_library_function_decl_with_spec (
    3714              :         get_identifier (PREFIX("adjustr_char4")), ". W . R ",
    3715              :         void_type_node, 3, pchar4_type_node, gfc_charlen_type_node,
    3716              :         pchar4_type_node);
    3717        31361 :   TREE_NOTHROW (gfor_fndecl_adjustr_char4) = 1;
    3718              : 
    3719        31361 :   gfor_fndecl_select_string_char4 = gfc_build_library_function_decl_with_spec (
    3720              :         get_identifier (PREFIX("select_string_char4")), ". R . R . ",
    3721              :         integer_type_node, 4, pvoid_type_node, integer_type_node,
    3722              :         pvoid_type_node, gfc_charlen_type_node);
    3723        31361 :   DECL_PURE_P (gfor_fndecl_select_string_char4) = 1;
    3724        31361 :   TREE_NOTHROW (gfor_fndecl_select_string_char4) = 1;
    3725              : 
    3726              : 
    3727              :   /* Conversion between character kinds.  */
    3728              : 
    3729        31361 :   gfor_fndecl_convert_char1_to_char4 = gfc_build_library_function_decl_with_spec (
    3730              :         get_identifier (PREFIX("convert_char1_to_char4")), ". w . R ",
    3731              :         void_type_node, 3, build_pointer_type (pchar4_type_node),
    3732              :         gfc_charlen_type_node, pchar1_type_node);
    3733              : 
    3734        31361 :   gfor_fndecl_convert_char4_to_char1 = gfc_build_library_function_decl_with_spec (
    3735              :         get_identifier (PREFIX("convert_char4_to_char1")), ". w . R ",
    3736              :         void_type_node, 3, build_pointer_type (pchar1_type_node),
    3737              :         gfc_charlen_type_node, pchar4_type_node);
    3738              : 
    3739              :   /* Misc. functions.  */
    3740              : 
    3741        31361 :   gfor_fndecl_ttynam = gfc_build_library_function_decl_with_spec (
    3742              :         get_identifier (PREFIX("ttynam")), ". W . . ",
    3743              :         void_type_node, 3, pchar_type_node, gfc_charlen_type_node,
    3744              :         integer_type_node);
    3745              : 
    3746        31361 :   gfor_fndecl_fdate = gfc_build_library_function_decl_with_spec (
    3747              :         get_identifier (PREFIX("fdate")), ". W . ",
    3748              :         void_type_node, 2, pchar_type_node, gfc_charlen_type_node);
    3749              : 
    3750        31361 :   gfor_fndecl_ctime = gfc_build_library_function_decl_with_spec (
    3751              :         get_identifier (PREFIX("ctime")), ". W . . ",
    3752              :         void_type_node, 3, pchar_type_node, gfc_charlen_type_node,
    3753              :         gfc_int8_type_node);
    3754              : 
    3755        31361 :   gfor_fndecl_random_init = gfc_build_library_function_decl (
    3756              :         get_identifier (PREFIX("random_init")),
    3757              :         void_type_node, 3, gfc_logical4_type_node, gfc_logical4_type_node,
    3758              :         gfc_int4_type_node);
    3759              : 
    3760              :  // gfor_fndecl_caf_rand_init is defined in the lib-coarray section below.
    3761              : 
    3762        31361 :   gfor_fndecl_sc_kind = gfc_build_library_function_decl_with_spec (
    3763              :         get_identifier (PREFIX("selected_char_kind")), ". . R ",
    3764              :         gfc_int4_type_node, 2, gfc_charlen_type_node, pchar_type_node);
    3765        31361 :   DECL_PURE_P (gfor_fndecl_sc_kind) = 1;
    3766        31361 :   TREE_NOTHROW (gfor_fndecl_sc_kind) = 1;
    3767              : 
    3768        31361 :   gfor_fndecl_si_kind = gfc_build_library_function_decl_with_spec (
    3769              :         get_identifier (PREFIX("selected_int_kind")), ". R ",
    3770              :         gfc_int4_type_node, 1, pvoid_type_node);
    3771        31361 :   DECL_PURE_P (gfor_fndecl_si_kind) = 1;
    3772        31361 :   TREE_NOTHROW (gfor_fndecl_si_kind) = 1;
    3773              : 
    3774        31361 :   gfor_fndecl_sl_kind = gfc_build_library_function_decl_with_spec (
    3775              :         get_identifier (PREFIX("selected_logical_kind")), ". R ",
    3776              :         gfc_int4_type_node, 1, pvoid_type_node);
    3777        31361 :   DECL_PURE_P (gfor_fndecl_sl_kind) = 1;
    3778        31361 :   TREE_NOTHROW (gfor_fndecl_sl_kind) = 1;
    3779              : 
    3780        31361 :   gfor_fndecl_sr_kind = gfc_build_library_function_decl_with_spec (
    3781              :         get_identifier (PREFIX("selected_real_kind2008")), ". R R ",
    3782              :         gfc_int4_type_node, 3, pvoid_type_node, pvoid_type_node,
    3783              :         pvoid_type_node);
    3784        31361 :   DECL_PURE_P (gfor_fndecl_sr_kind) = 1;
    3785        31361 :   TREE_NOTHROW (gfor_fndecl_sr_kind) = 1;
    3786              : 
    3787        31361 :   gfor_fndecl_system_clock4 = gfc_build_library_function_decl (
    3788              :         get_identifier (PREFIX("system_clock_4")),
    3789              :         void_type_node, 3, gfc_pint4_type_node, gfc_pint4_type_node,
    3790              :         gfc_pint4_type_node);
    3791              : 
    3792        31361 :   gfor_fndecl_system_clock8 = gfc_build_library_function_decl (
    3793              :         get_identifier (PREFIX("system_clock_8")),
    3794              :         void_type_node, 3, gfc_pint8_type_node, gfc_pint8_type_node,
    3795              :         gfc_pint8_type_node);
    3796              : 
    3797              :   /* Power functions.  */
    3798        31361 :   {
    3799        31361 :     tree ctype, rtype, itype, jtype;
    3800        31361 :     int rkind, ikind, jkind;
    3801              : #define NIKINDS 3
    3802              : #define NRKINDS 4
    3803              : #define NUKINDS 5
    3804        31361 :     static const int ikinds[NIKINDS] = {4, 8, 16};
    3805        31361 :     static const int rkinds[NRKINDS] = {4, 8, 10, 16};
    3806        31361 :     static const int ukinds[NUKINDS] = {1, 2, 4, 8, 16};
    3807        31361 :     char name[PREFIX_LEN + 12]; /* _gfortran_pow_?n_?n */
    3808              : 
    3809       125444 :     for (ikind=0; ikind < NIKINDS; ikind++)
    3810              :       {
    3811        94083 :         itype = gfc_get_int_type (ikinds[ikind]);
    3812              : 
    3813       470415 :         for (jkind=0; jkind < NIKINDS; jkind++)
    3814              :           {
    3815       282249 :             jtype = gfc_get_int_type (ikinds[jkind]);
    3816       282249 :             if (itype && jtype)
    3817              :               {
    3818       280214 :                 sprintf (name, PREFIX("pow_i%d_i%d"), ikinds[ikind],
    3819              :                         ikinds[jkind]);
    3820       560428 :                 gfor_fndecl_math_powi[jkind][ikind].integer =
    3821       280214 :                   gfc_build_library_function_decl (get_identifier (name),
    3822              :                     jtype, 2, jtype, itype);
    3823       280214 :                 TREE_READONLY (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
    3824       280214 :                 TREE_NOTHROW (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
    3825              :               }
    3826              :           }
    3827              : 
    3828       470415 :         for (rkind = 0; rkind < NRKINDS; rkind ++)
    3829              :           {
    3830       376332 :             rtype = gfc_get_real_type (rkinds[rkind]);
    3831       376332 :             if (rtype && itype)
    3832              :               {
    3833       374704 :                 sprintf (name, PREFIX("pow_r%d_i%d"),
    3834              :                          gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
    3835              :                          ikinds[ikind]);
    3836       749408 :                 gfor_fndecl_math_powi[rkind][ikind].real =
    3837       374704 :                   gfc_build_library_function_decl (get_identifier (name),
    3838              :                     rtype, 2, rtype, itype);
    3839       374704 :                 TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
    3840       374704 :                 TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
    3841              :               }
    3842              : 
    3843       376332 :             ctype = gfc_get_complex_type (rkinds[rkind]);
    3844       376332 :             if (ctype && itype)
    3845              :               {
    3846       374704 :                 sprintf (name, PREFIX("pow_c%d_i%d"),
    3847              :                          gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
    3848              :                          ikinds[ikind]);
    3849       749408 :                 gfor_fndecl_math_powi[rkind][ikind].cmplx =
    3850       374704 :                   gfc_build_library_function_decl (get_identifier (name),
    3851              :                     ctype, 2,ctype, itype);
    3852       374704 :                 TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
    3853       374704 :                 TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
    3854              :               }
    3855              :           }
    3856              :         /* For unsigned types, we have every power for every type.  */
    3857       564498 :         for (int base = 0; base < NUKINDS; base++)
    3858              :           {
    3859       470415 :             tree base_type = gfc_get_unsigned_type (ukinds[base]);
    3860      2822490 :             for (int expon = 0; expon < NUKINDS; expon++)
    3861              :               {
    3862      2352075 :                 tree expon_type = gfc_get_unsigned_type (ukinds[base]);
    3863      2352075 :                 if (base_type && expon_type)
    3864              :                   {
    3865        18375 :                     sprintf (name, PREFIX("pow_m%d_m%d"), ukinds[base],
    3866        18375 :                          ukinds[expon]);
    3867        36750 :                     gfor_fndecl_unsigned_pow_list [base][expon] =
    3868        18375 :                       gfc_build_library_function_decl (get_identifier (name),
    3869              :                          base_type, 2, base_type, expon_type);
    3870        18375 :                     TREE_READONLY (gfor_fndecl_unsigned_pow_list[base][expon]) = 1;
    3871        18375 :                     TREE_NOTHROW (gfor_fndecl_unsigned_pow_list[base][expon]) = 1;
    3872              :                   }
    3873              :               }
    3874              :           }
    3875              :       }
    3876              : #undef NIKINDS
    3877              : #undef NRKINDS
    3878              : #undef NUKINDS
    3879              :   }
    3880              : 
    3881        31361 :   gfor_fndecl_math_ishftc4 = gfc_build_library_function_decl (
    3882              :         get_identifier (PREFIX("ishftc4")),
    3883              :         gfc_int4_type_node, 3, gfc_int4_type_node, gfc_int4_type_node,
    3884              :         gfc_int4_type_node);
    3885        31361 :   TREE_READONLY (gfor_fndecl_math_ishftc4) = 1;
    3886        31361 :   TREE_NOTHROW (gfor_fndecl_math_ishftc4) = 1;
    3887              : 
    3888        31361 :   gfor_fndecl_math_ishftc8 = gfc_build_library_function_decl (
    3889              :         get_identifier (PREFIX("ishftc8")),
    3890              :         gfc_int8_type_node, 3, gfc_int8_type_node, gfc_int4_type_node,
    3891              :         gfc_int4_type_node);
    3892        31361 :   TREE_READONLY (gfor_fndecl_math_ishftc8) = 1;
    3893        31361 :   TREE_NOTHROW (gfor_fndecl_math_ishftc8) = 1;
    3894              : 
    3895        31361 :   if (gfc_int16_type_node)
    3896              :     {
    3897        30954 :       gfor_fndecl_math_ishftc16 = gfc_build_library_function_decl (
    3898              :         get_identifier (PREFIX("ishftc16")),
    3899              :         gfc_int16_type_node, 3, gfc_int16_type_node, gfc_int4_type_node,
    3900              :         gfc_int4_type_node);
    3901        30954 :       TREE_READONLY (gfor_fndecl_math_ishftc16) = 1;
    3902        30954 :       TREE_NOTHROW (gfor_fndecl_math_ishftc16) = 1;
    3903              :     }
    3904              : 
    3905              :   /* BLAS functions.  */
    3906        31361 :   {
    3907        31361 :     tree pint = build_pointer_type (integer_type_node);
    3908        31361 :     tree ps = build_pointer_type (gfc_get_real_type (gfc_default_real_kind));
    3909        31361 :     tree pd = build_pointer_type (gfc_get_real_type (gfc_default_double_kind));
    3910        31361 :     tree pc = build_pointer_type (gfc_get_complex_type (gfc_default_real_kind));
    3911        31361 :     tree pz = build_pointer_type
    3912        31361 :                 (gfc_get_complex_type (gfc_default_double_kind));
    3913              : 
    3914        62722 :     gfor_fndecl_sgemm = gfc_build_library_function_decl
    3915        32136 :                           (get_identifier
    3916              :                              (flag_underscoring ? "sgemm_" : "sgemm"),
    3917              :                            void_type_node, 15, pchar_type_node,
    3918              :                            pchar_type_node, pint, pint, pint, ps, ps, pint,
    3919              :                            ps, pint, ps, ps, pint, integer_type_node,
    3920              :                            integer_type_node);
    3921        62722 :     gfor_fndecl_dgemm = gfc_build_library_function_decl
    3922        32136 :                           (get_identifier
    3923              :                              (flag_underscoring ? "dgemm_" : "dgemm"),
    3924              :                            void_type_node, 15, pchar_type_node,
    3925              :                            pchar_type_node, pint, pint, pint, pd, pd, pint,
    3926              :                            pd, pint, pd, pd, pint, integer_type_node,
    3927              :                            integer_type_node);
    3928        62722 :     gfor_fndecl_cgemm = gfc_build_library_function_decl
    3929        32136 :                           (get_identifier
    3930              :                              (flag_underscoring ? "cgemm_" : "cgemm"),
    3931              :                            void_type_node, 15, pchar_type_node,
    3932              :                            pchar_type_node, pint, pint, pint, pc, pc, pint,
    3933              :                            pc, pint, pc, pc, pint, integer_type_node,
    3934              :                            integer_type_node);
    3935        62722 :     gfor_fndecl_zgemm = gfc_build_library_function_decl
    3936        32136 :                           (get_identifier
    3937              :                              (flag_underscoring ? "zgemm_" : "zgemm"),
    3938              :                            void_type_node, 15, pchar_type_node,
    3939              :                            pchar_type_node, pint, pint, pint, pz, pz, pint,
    3940              :                            pz, pint, pz, pz, pint, integer_type_node,
    3941              :                            integer_type_node);
    3942              :   }
    3943              : 
    3944              :   /* Other functions.  */
    3945        31361 :   gfor_fndecl_iargc = gfc_build_library_function_decl (
    3946              :         get_identifier (PREFIX ("iargc")), gfc_int4_type_node, 0);
    3947        31361 :   TREE_NOTHROW (gfor_fndecl_iargc) = 1;
    3948              : 
    3949        31361 :   gfor_fndecl_kill_sub = gfc_build_library_function_decl (
    3950              :         get_identifier (PREFIX ("kill_sub")), void_type_node,
    3951              :         3, gfc_int4_type_node, gfc_int4_type_node, gfc_pint4_type_node);
    3952              : 
    3953        31361 :   gfor_fndecl_kill = gfc_build_library_function_decl (
    3954              :         get_identifier (PREFIX ("kill")), gfc_int4_type_node,
    3955              :         2, gfc_int4_type_node, gfc_int4_type_node);
    3956              : 
    3957        31361 :   gfor_fndecl_is_contiguous0 = gfc_build_library_function_decl_with_spec (
    3958              :         get_identifier (PREFIX("is_contiguous0")), ". R ",
    3959              :         gfc_int4_type_node, 1, pvoid_type_node);
    3960        31361 :   DECL_PURE_P (gfor_fndecl_is_contiguous0) = 1;
    3961        31361 :   TREE_NOTHROW (gfor_fndecl_is_contiguous0) = 1;
    3962              : 
    3963        31361 :   gfor_fndecl_fstat_i4_sub = gfc_build_library_function_decl (
    3964              :         get_identifier (PREFIX ("fstat_i4_sub")), void_type_node,
    3965              :         3, gfc_pint4_type_node, gfc_pint4_type_node, gfc_pint4_type_node);
    3966              : 
    3967        31361 :   gfor_fndecl_fstat_i8_sub = gfc_build_library_function_decl (
    3968              :         get_identifier (PREFIX ("fstat_i8_sub")), void_type_node,
    3969              :         3, gfc_pint8_type_node, gfc_pint8_type_node, gfc_pint8_type_node);
    3970              : 
    3971        31361 :   gfor_fndecl_lstat_i4_sub = gfc_build_library_function_decl (
    3972              :         get_identifier (PREFIX ("lstat_i4_sub")), void_type_node,
    3973              :         4, pchar_type_node, gfc_pint4_type_node, gfc_pint4_type_node,
    3974              :         gfc_charlen_type_node);
    3975              : 
    3976        31361 :   gfor_fndecl_lstat_i8_sub = gfc_build_library_function_decl (
    3977              :         get_identifier (PREFIX ("lstat_i8_sub")), void_type_node,
    3978              :         4, pchar_type_node, gfc_pint8_type_node, gfc_pint8_type_node,
    3979              :         gfc_charlen_type_node);
    3980              : 
    3981        31361 :   gfor_fndecl_stat_i4_sub = gfc_build_library_function_decl (
    3982              :         get_identifier (PREFIX ("stat_i4_sub")), void_type_node,
    3983              :         4, pchar_type_node, gfc_pint4_type_node, gfc_pint4_type_node,
    3984              :         gfc_charlen_type_node);
    3985              : 
    3986        31361 :   gfor_fndecl_stat_i8_sub = gfc_build_library_function_decl (
    3987              :         get_identifier (PREFIX ("stat_i8_sub")), void_type_node,
    3988              :         4, pchar_type_node, gfc_pint8_type_node, gfc_pint8_type_node,
    3989              :         gfc_charlen_type_node);
    3990        31361 : }
    3991              : 
    3992              : 
    3993              : /* Make prototypes for runtime library functions.  */
    3994              : 
    3995              : void
    3996        31361 : gfc_build_builtin_function_decls (void)
    3997              : {
    3998        31361 :   tree gfc_int8_type_node = gfc_get_int_type (8);
    3999              : 
    4000        31361 :   gfor_fndecl_stop_numeric = gfc_build_library_function_decl (
    4001              :         get_identifier (PREFIX("stop_numeric")),
    4002              :         void_type_node, 2, integer_type_node, boolean_type_node);
    4003              :   /* STOP doesn't return.  */
    4004        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric) = 1;
    4005              : 
    4006        31361 :   gfor_fndecl_stop_string = gfc_build_library_function_decl_with_spec (
    4007              :         get_identifier (PREFIX("stop_string")), ". R . . ",
    4008              :         void_type_node, 3, pchar_type_node, size_type_node,
    4009              :         boolean_type_node);
    4010              :   /* STOP doesn't return.  */
    4011        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_stop_string) = 1;
    4012              : 
    4013        31361 :   gfor_fndecl_error_stop_numeric = gfc_build_library_function_decl (
    4014              :         get_identifier (PREFIX("error_stop_numeric")),
    4015              :         void_type_node, 2, integer_type_node, boolean_type_node);
    4016              :   /* ERROR STOP doesn't return.  */
    4017        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_error_stop_numeric) = 1;
    4018              : 
    4019        31361 :   gfor_fndecl_error_stop_string = gfc_build_library_function_decl_with_spec (
    4020              :         get_identifier (PREFIX("error_stop_string")), ". R . . ",
    4021              :         void_type_node, 3, pchar_type_node, size_type_node,
    4022              :         boolean_type_node);
    4023              :   /* ERROR STOP doesn't return.  */
    4024        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1;
    4025              : 
    4026        31361 :   gfor_fndecl_pause_numeric = gfc_build_library_function_decl (
    4027              :         get_identifier (PREFIX("pause_numeric")),
    4028              :         void_type_node, 1, gfc_int8_type_node);
    4029              : 
    4030        31361 :   gfor_fndecl_pause_string = gfc_build_library_function_decl_with_spec (
    4031              :         get_identifier (PREFIX("pause_string")), ". R . ",
    4032              :         void_type_node, 2, pchar_type_node, size_type_node);
    4033              : 
    4034        31361 :   gfor_fndecl_runtime_error = gfc_build_library_function_decl_with_spec (
    4035              :         get_identifier (PREFIX("runtime_error")), ". R ",
    4036              :         void_type_node, -1, pchar_type_node);
    4037              :   /* The runtime_error function does not return.  */
    4038        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_runtime_error) = 1;
    4039              : 
    4040        31361 :   gfor_fndecl_runtime_error_at = gfc_build_library_function_decl_with_spec (
    4041              :         get_identifier (PREFIX("runtime_error_at")), ". R R ",
    4042              :         void_type_node, -2, pchar_type_node, pchar_type_node);
    4043              :   /* The runtime_error_at function does not return.  */
    4044        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_runtime_error_at) = 1;
    4045              : 
    4046        31361 :   gfor_fndecl_runtime_warning_at = gfc_build_library_function_decl_with_spec (
    4047              :         get_identifier (PREFIX("runtime_warning_at")), ". R R ",
    4048              :         void_type_node, -2, pchar_type_node, pchar_type_node);
    4049              : 
    4050        31361 :   gfor_fndecl_generate_error = gfc_build_library_function_decl_with_spec (
    4051              :         get_identifier (PREFIX("generate_error")), ". W . R ",
    4052              :         void_type_node, 3, pvoid_type_node, integer_type_node,
    4053              :         pchar_type_node);
    4054              : 
    4055        31361 :   gfor_fndecl_os_error_at = gfc_build_library_function_decl_with_spec (
    4056              :         get_identifier (PREFIX("os_error_at")), ". R R ",
    4057              :         void_type_node, -2, pchar_type_node, pchar_type_node);
    4058              :   /* The os_error_at function does not return.  */
    4059        31361 :   TREE_THIS_VOLATILE (gfor_fndecl_os_error_at) = 1;
    4060              : 
    4061        31361 :   gfor_fndecl_set_args = gfc_build_library_function_decl (
    4062              :         get_identifier (PREFIX("set_args")),
    4063              :         void_type_node, 2, integer_type_node,
    4064              :         build_pointer_type (pchar_type_node));
    4065              : 
    4066        31361 :   gfor_fndecl_set_fpe = gfc_build_library_function_decl (
    4067              :         get_identifier (PREFIX("set_fpe")),
    4068              :         void_type_node, 1, integer_type_node);
    4069              : 
    4070        31361 :   gfor_fndecl_ieee_procedure_entry = gfc_build_library_function_decl (
    4071              :         get_identifier (PREFIX("ieee_procedure_entry")),
    4072              :         void_type_node, 1, pvoid_type_node);
    4073              : 
    4074        31361 :   gfor_fndecl_ieee_procedure_exit = gfc_build_library_function_decl (
    4075              :         get_identifier (PREFIX("ieee_procedure_exit")),
    4076              :         void_type_node, 1, pvoid_type_node);
    4077              : 
    4078              :   /* Keep the array dimension in sync with the call, later in this file.  */
    4079        31361 :   gfor_fndecl_set_options = gfc_build_library_function_decl_with_spec (
    4080              :         get_identifier (PREFIX("set_options")), ". . R ",
    4081              :         void_type_node, 2, integer_type_node,
    4082              :         build_pointer_type (integer_type_node));
    4083              : 
    4084        31361 :   gfor_fndecl_set_convert = gfc_build_library_function_decl (
    4085              :         get_identifier (PREFIX("set_convert")),
    4086              :         void_type_node, 1, integer_type_node);
    4087              : 
    4088        31361 :   gfor_fndecl_set_record_marker = gfc_build_library_function_decl (
    4089              :         get_identifier (PREFIX("set_record_marker")),
    4090              :         void_type_node, 1, integer_type_node);
    4091              : 
    4092        31361 :   gfor_fndecl_set_max_subrecord_length = gfc_build_library_function_decl (
    4093              :         get_identifier (PREFIX("set_max_subrecord_length")),
    4094              :         void_type_node, 1, integer_type_node);
    4095              : 
    4096        31361 :   gfor_fndecl_in_pack = gfc_build_library_function_decl_with_spec (
    4097              :         get_identifier (PREFIX("internal_pack")), ". r ",
    4098              :         pvoid_type_node, 1, pvoid_type_node);
    4099              : 
    4100        31361 :   gfor_fndecl_in_unpack = gfc_build_library_function_decl_with_spec (
    4101              :         get_identifier (PREFIX("internal_unpack")), ". w R ",
    4102              :         void_type_node, 2, pvoid_type_node, pvoid_type_node);
    4103              : 
    4104        31361 :   gfor_fndecl_in_pack_class = gfc_build_library_function_decl_with_spec (
    4105              :     get_identifier (PREFIX ("internal_pack_class")), ". w R r r ",
    4106              :     void_type_node, 4, pvoid_type_node, pvoid_type_node, size_type_node,
    4107              :     integer_type_node);
    4108              : 
    4109        31361 :   gfor_fndecl_in_unpack_class = gfc_build_library_function_decl_with_spec (
    4110              :     get_identifier (PREFIX ("internal_unpack_class")), ". w R r r ",
    4111              :     void_type_node, 4, pvoid_type_node, pvoid_type_node, size_type_node,
    4112              :     integer_type_node);
    4113              : 
    4114        31361 :   gfor_fndecl_associated = gfc_build_library_function_decl_with_spec (
    4115              :     get_identifier (PREFIX ("associated")), ". R R ", integer_type_node, 2,
    4116              :     ppvoid_type_node, ppvoid_type_node);
    4117        31361 :   DECL_PURE_P (gfor_fndecl_associated) = 1;
    4118        31361 :   TREE_NOTHROW (gfor_fndecl_associated) = 1;
    4119              : 
    4120              :   /* Coarray library calls.  */
    4121        31361 :   if (flag_coarray == GFC_FCOARRAY_LIB)
    4122              :     {
    4123          462 :       tree pint_type, pppchar_type, psize_type;
    4124              : 
    4125          462 :       pint_type = build_pointer_type (integer_type_node);
    4126          462 :       pppchar_type
    4127          462 :         = build_pointer_type (build_pointer_type (pchar_type_node));
    4128          462 :       psize_type = build_pointer_type (size_type_node);
    4129              : 
    4130          462 :       gfor_fndecl_caf_init = gfc_build_library_function_decl_with_spec (
    4131              :         get_identifier (PREFIX("caf_init")), ". W W ",
    4132              :         void_type_node, 2, pint_type, pppchar_type);
    4133              : 
    4134          462 :       gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
    4135              :         get_identifier (PREFIX("caf_finalize")), void_type_node, 0);
    4136              : 
    4137          462 :       gfor_fndecl_caf_this_image = gfc_build_library_function_decl_with_spec (
    4138              :         get_identifier (PREFIX ("caf_this_image")), ". r ", integer_type_node,
    4139              :         1, pvoid_type_node);
    4140              : 
    4141          462 :       gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
    4142              :         get_identifier (PREFIX("caf_num_images")), integer_type_node,
    4143              :         2, integer_type_node, integer_type_node);
    4144              : 
    4145          462 :       gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
    4146              :         get_identifier (PREFIX("caf_register")), ". . . W w w w . ",
    4147              :         void_type_node, 7,
    4148              :         size_type_node, integer_type_node, ppvoid_type_node, pvoid_type_node,
    4149              :         pint_type, pchar_type_node, size_type_node);
    4150              : 
    4151          462 :       gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec (
    4152              :         get_identifier (PREFIX("caf_deregister")), ". W . w w . ",
    4153              :         void_type_node, 5,
    4154              :         ppvoid_type_node, integer_type_node, pint_type, pchar_type_node,
    4155              :         size_type_node);
    4156              : 
    4157          462 :       gfor_fndecl_caf_register_accessor
    4158          462 :         = gfc_build_library_function_decl_with_spec (
    4159              :           get_identifier (PREFIX ("caf_register_accessor")), ". r r ",
    4160              :           void_type_node, 2, integer_type_node, pvoid_type_node);
    4161              : 
    4162          462 :       gfor_fndecl_caf_register_accessors_finish
    4163          462 :         = gfc_build_library_function_decl_with_spec (
    4164              :           get_identifier (PREFIX ("caf_register_accessors_finish")), ". ",
    4165              :           void_type_node, 0);
    4166              : 
    4167          462 :       gfor_fndecl_caf_get_remote_function_index
    4168          462 :         = gfc_build_library_function_decl_with_spec (
    4169              :           get_identifier (PREFIX ("caf_get_remote_function_index")), ". r ",
    4170              :           integer_type_node, 1, integer_type_node);
    4171              : 
    4172          462 :       gfor_fndecl_caf_get_from_remote
    4173          462 :         = gfc_build_library_function_decl_with_spec (
    4174              :           get_identifier (PREFIX ("caf_get_from_remote")),
    4175              :           ". r r r r r w w w r r w r w r r ", void_type_node, 15,
    4176              :           pvoid_type_node, pvoid_type_node, psize_type, integer_type_node,
    4177              :           size_type_node, ppvoid_type_node, psize_type, pvoid_type_node,
    4178              :           boolean_type_node, integer_type_node, pvoid_type_node, size_type_node,
    4179              :           pint_type, pvoid_type_node, pint_type);
    4180              : 
    4181          462 :       gfor_fndecl_caf_send_to_remote
    4182          462 :         = gfc_build_library_function_decl_with_spec (
    4183              :           get_identifier (PREFIX ("caf_send_to_remote")),
    4184              :           ". r r r r r r r r r w r w r r ", void_type_node, 14, pvoid_type_node,
    4185              :           pvoid_type_node, psize_type, integer_type_node, size_type_node,
    4186              :           ppvoid_type_node, psize_type, pvoid_type_node, integer_type_node,
    4187              :           pvoid_type_node, size_type_node, pint_type, pvoid_type_node,
    4188              :           pint_type);
    4189              : 
    4190          462 :       gfor_fndecl_caf_transfer_between_remotes
    4191          462 :         = gfc_build_library_function_decl_with_spec (
    4192              :           get_identifier (PREFIX ("caf_transfer_between_remotes")),
    4193              :           ". r r r r r r r r r r r r r r r r w w r r ", void_type_node, 20,
    4194              :           pvoid_type_node, pvoid_type_node, psize_type, integer_type_node,
    4195              :           integer_type_node, pvoid_type_node, size_type_node, pvoid_type_node,
    4196              :           pvoid_type_node, psize_type, integer_type_node, integer_type_node,
    4197              :           pvoid_type_node, size_type_node, size_type_node, boolean_type_node,
    4198              :           pint_type, pint_type, pvoid_type_node, pint_type);
    4199              : 
    4200          462 :       gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
    4201              :         get_identifier (PREFIX ("caf_sync_all")), ". w w . ", void_type_node, 3,
    4202              :         pint_type, pchar_type_node, size_type_node);
    4203              : 
    4204          462 :       gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec (
    4205              :         get_identifier (PREFIX("caf_sync_memory")), ". w w . ", void_type_node,
    4206              :         3, pint_type, pchar_type_node, size_type_node);
    4207              : 
    4208          462 :       gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec (
    4209              :         get_identifier (PREFIX("caf_sync_images")), ". . r w w . ", void_type_node,
    4210              :         5, integer_type_node, pint_type, pint_type,
    4211              :         pchar_type_node, size_type_node);
    4212              : 
    4213          462 :       gfor_fndecl_caf_error_stop = gfc_build_library_function_decl (
    4214              :         get_identifier (PREFIX("caf_error_stop")),
    4215              :         void_type_node, 1, integer_type_node);
    4216              :       /* CAF's ERROR STOP doesn't return.  */
    4217          462 :       TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop) = 1;
    4218              : 
    4219          462 :       gfor_fndecl_caf_error_stop_str = gfc_build_library_function_decl_with_spec (
    4220              :         get_identifier (PREFIX("caf_error_stop_str")), ". r . ",
    4221              :         void_type_node, 2, pchar_type_node, size_type_node);
    4222              :       /* CAF's ERROR STOP doesn't return.  */
    4223          462 :       TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1;
    4224              : 
    4225          462 :       gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl (
    4226              :         get_identifier (PREFIX("caf_stop_numeric")),
    4227              :         void_type_node, 1, integer_type_node);
    4228              :       /* CAF's STOP doesn't return.  */
    4229          462 :       TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1;
    4230              : 
    4231          462 :       gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec (
    4232              :         get_identifier (PREFIX("caf_stop_str")), ". r . ",
    4233              :         void_type_node, 2, pchar_type_node, size_type_node);
    4234              :       /* CAF's STOP doesn't return.  */
    4235          462 :       TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
    4236              : 
    4237          462 :       gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
    4238              :         get_identifier (PREFIX("caf_atomic_define")), ". r . . w w . . ",
    4239              :         void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
    4240              :         pvoid_type_node, pint_type, integer_type_node, integer_type_node);
    4241              : 
    4242          462 :       gfor_fndecl_caf_atomic_ref = gfc_build_library_function_decl_with_spec (
    4243              :         get_identifier (PREFIX("caf_atomic_ref")), ". r . . w w . . ",
    4244              :         void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
    4245              :         pvoid_type_node, pint_type, integer_type_node, integer_type_node);
    4246              : 
    4247          462 :       gfor_fndecl_caf_atomic_cas = gfc_build_library_function_decl_with_spec (
    4248              :         get_identifier (PREFIX("caf_atomic_cas")), ". r . . w r r w . . ",
    4249              :         void_type_node, 9, pvoid_type_node, size_type_node, integer_type_node,
    4250              :         pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
    4251              :         integer_type_node, integer_type_node);
    4252              : 
    4253          462 :       gfor_fndecl_caf_atomic_op = gfc_build_library_function_decl_with_spec (
    4254              :         get_identifier (PREFIX("caf_atomic_op")), ". . r . . r w w . . ",
    4255              :         void_type_node, 9, integer_type_node, pvoid_type_node, size_type_node,
    4256              :         integer_type_node, pvoid_type_node, pvoid_type_node, pint_type,
    4257              :         integer_type_node, integer_type_node);
    4258              : 
    4259          462 :       gfor_fndecl_caf_lock = gfc_build_library_function_decl_with_spec (
    4260              :         get_identifier (PREFIX("caf_lock")), ". r . . w w w . ",
    4261              :         void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
    4262              :         pint_type, pint_type, pchar_type_node, size_type_node);
    4263              : 
    4264          462 :       gfor_fndecl_caf_unlock = gfc_build_library_function_decl_with_spec (
    4265              :         get_identifier (PREFIX("caf_unlock")), ". r . . w w . ",
    4266              :         void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
    4267              :         pint_type, pchar_type_node, size_type_node);
    4268              : 
    4269          462 :       gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec (
    4270              :         get_identifier (PREFIX("caf_event_post")), ". r . . w w . ",
    4271              :         void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
    4272              :         pint_type, pchar_type_node, size_type_node);
    4273              : 
    4274          462 :       gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec (
    4275              :         get_identifier (PREFIX("caf_event_wait")), ". r . . w w . ",
    4276              :         void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
    4277              :         pint_type, pchar_type_node, size_type_node);
    4278              : 
    4279          462 :       gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec (
    4280              :         get_identifier (PREFIX("caf_event_query")), ". r . . w w ",
    4281              :         void_type_node, 5, pvoid_type_node, size_type_node, integer_type_node,
    4282              :         pint_type, pint_type);
    4283              : 
    4284          462 :       gfor_fndecl_caf_fail_image = gfc_build_library_function_decl (
    4285              :         get_identifier (PREFIX("caf_fail_image")), void_type_node, 0);
    4286              :       /* CAF's FAIL doesn't return.  */
    4287          462 :       TREE_THIS_VOLATILE (gfor_fndecl_caf_fail_image) = 1;
    4288              : 
    4289          462 :       gfor_fndecl_caf_failed_images
    4290          462 :         = gfc_build_library_function_decl_with_spec (
    4291              :             get_identifier (PREFIX("caf_failed_images")), ". w . r ",
    4292              :             void_type_node, 3, pvoid_type_node, ppvoid_type_node,
    4293              :             integer_type_node);
    4294              : 
    4295          462 :       gfor_fndecl_caf_form_team = gfc_build_library_function_decl_with_spec (
    4296              :         get_identifier (PREFIX ("caf_form_team")), ". r w r w w w ",
    4297              :         void_type_node, 6, integer_type_node, ppvoid_type_node, pint_type,
    4298              :         pint_type, pchar_type_node, size_type_node);
    4299              : 
    4300          462 :       gfor_fndecl_caf_change_team = gfc_build_library_function_decl_with_spec (
    4301              :         get_identifier (PREFIX ("caf_change_team")), ". r w w w ",
    4302              :         void_type_node, 4, pvoid_type_node, pint_type, pchar_type_node,
    4303              :         size_type_node);
    4304              : 
    4305          462 :       gfor_fndecl_caf_end_team = gfc_build_library_function_decl_with_spec (
    4306              :         get_identifier (PREFIX ("caf_end_team")), ". w w w ", void_type_node, 3,
    4307              :         pint_type, pchar_type_node, size_type_node);
    4308              : 
    4309          462 :       gfor_fndecl_caf_get_team = gfc_build_library_function_decl_with_spec (
    4310              :         get_identifier (PREFIX ("caf_get_team")), ". r ", pvoid_type_node, 1,
    4311              :         pint_type);
    4312              : 
    4313          462 :       gfor_fndecl_caf_sync_team = gfc_build_library_function_decl_with_spec (
    4314              :         get_identifier (PREFIX ("caf_sync_team")), ". r w w w ", void_type_node,
    4315              :         4, pvoid_type_node, pint_type, pchar_type_node, size_type_node);
    4316              : 
    4317          462 :       gfor_fndecl_caf_team_number = gfc_build_library_function_decl_with_spec (
    4318              :         get_identifier (PREFIX ("caf_team_number")), ". r ", integer_type_node,
    4319              :         1, pvoid_type_node);
    4320              : 
    4321          462 :       gfor_fndecl_caf_image_status = gfc_build_library_function_decl_with_spec (
    4322              :         get_identifier (PREFIX ("caf_image_status")), ". r r ",
    4323              :         integer_type_node, 2, integer_type_node, ppvoid_type_node);
    4324              : 
    4325          462 :       gfor_fndecl_caf_stopped_images
    4326          462 :         = gfc_build_library_function_decl_with_spec (
    4327              :             get_identifier (PREFIX("caf_stopped_images")), ". w r r ",
    4328              :             void_type_node, 3, pvoid_type_node, ppvoid_type_node,
    4329              :             integer_type_node);
    4330              : 
    4331          462 :       gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec (
    4332              :         get_identifier (PREFIX("caf_co_broadcast")), ". w . w w . ",
    4333              :         void_type_node, 5, pvoid_type_node, integer_type_node,
    4334              :         pint_type, pchar_type_node, size_type_node);
    4335              : 
    4336          462 :       gfor_fndecl_co_max = gfc_build_library_function_decl_with_spec (
    4337              :         get_identifier (PREFIX("caf_co_max")), ". w . w w . . ",
    4338              :         void_type_node, 6, pvoid_type_node, integer_type_node,
    4339              :         pint_type, pchar_type_node, integer_type_node, size_type_node);
    4340              : 
    4341          462 :       gfor_fndecl_co_min = gfc_build_library_function_decl_with_spec (
    4342              :         get_identifier (PREFIX("caf_co_min")), ". w . w w . . ",
    4343              :         void_type_node, 6, pvoid_type_node, integer_type_node,
    4344              :         pint_type, pchar_type_node, integer_type_node, size_type_node);
    4345              : 
    4346          462 :       gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec (
    4347              :         get_identifier (PREFIX("caf_co_reduce")), ". w r . . w w . . ",
    4348              :         void_type_node, 8, pvoid_type_node,
    4349              :         build_pointer_type (build_varargs_function_type_list (void_type_node,
    4350              :                                                               NULL_TREE)),
    4351              :         integer_type_node, integer_type_node, pint_type, pchar_type_node,
    4352              :         integer_type_node, size_type_node);
    4353              : 
    4354          462 :       gfor_fndecl_co_sum = gfc_build_library_function_decl_with_spec (
    4355              :         get_identifier (PREFIX("caf_co_sum")), ". w . w w . ",
    4356              :         void_type_node, 5, pvoid_type_node, integer_type_node,
    4357              :         pint_type, pchar_type_node, size_type_node);
    4358              : 
    4359          462 :       gfor_fndecl_caf_is_present_on_remote
    4360          462 :         = gfc_build_library_function_decl_with_spec (
    4361              :           get_identifier (PREFIX ("caf_is_present_on_remote")), ". r r r r r ",
    4362              :           integer_type_node, 5, pvoid_type_node, integer_type_node,
    4363              :           integer_type_node, pvoid_type_node, size_type_node);
    4364              : 
    4365          462 :       gfor_fndecl_caf_random_init = gfc_build_library_function_decl (
    4366              :             get_identifier (PREFIX("caf_random_init")),
    4367              :             void_type_node, 2, logical_type_node, logical_type_node);
    4368              :     }
    4369              : 
    4370        31361 :   gfc_build_intrinsic_function_decls ();
    4371        31361 :   gfc_build_intrinsic_lib_fndecls ();
    4372        31361 :   gfc_build_io_library_fndecls ();
    4373        31361 : }
    4374              : 
    4375              : 
    4376              : /* Evaluate the length of dummy character variables.  */
    4377              : 
    4378              : static void
    4379          750 : gfc_trans_dummy_character (gfc_symbol *sym, gfc_charlen *cl,
    4380              :                            gfc_wrapped_block *block)
    4381              : {
    4382          750 :   stmtblock_t init;
    4383              : 
    4384          750 :   gfc_finish_decl (cl->backend_decl);
    4385              : 
    4386          750 :   gfc_start_block (&init);
    4387              : 
    4388              :   /* Evaluate the string length expression.  */
    4389          750 :   gfc_conv_string_length (cl, NULL, &init);
    4390              : 
    4391          750 :   gfc_trans_vla_type_sizes (sym, &init);
    4392              : 
    4393          750 :   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
    4394          750 : }
    4395              : 
    4396              : 
    4397              : /* Allocate and cleanup an automatic character variable.  */
    4398              : 
    4399              : static void
    4400          354 : gfc_trans_auto_character_variable (gfc_symbol * sym, gfc_wrapped_block * block)
    4401              : {
    4402          354 :   stmtblock_t init;
    4403          354 :   tree decl;
    4404          354 :   tree tmp;
    4405          354 :   bool back;
    4406              : 
    4407          354 :   gcc_assert (sym->backend_decl);
    4408          354 :   gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length);
    4409              : 
    4410          354 :   gfc_init_block (&init);
    4411              : 
    4412              :   /* In the case of non-dummy symbols with dependencies on an old-fashioned
    4413              :      function result (ie. proc_name = proc_name->result), gfc_add_init_cleanup
    4414              :      must be called with the last, optional argument false so that the process
    4415              :      ing of the character length occurs after the processing of the result.  */
    4416          354 :   back = sym->fn_result_dep;
    4417              : 
    4418              :   /* Evaluate the string length expression.  */
    4419          354 :   gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
    4420              : 
    4421          354 :   gfc_trans_vla_type_sizes (sym, &init);
    4422              : 
    4423          354 :   decl = sym->backend_decl;
    4424              : 
    4425              :   /* Emit a DECL_EXPR for this variable, which will cause the
    4426              :      gimplifier to allocate storage, and all that good stuff.  */
    4427          354 :   tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
    4428          354 :   gfc_add_expr_to_block (&init, tmp);
    4429              : 
    4430          354 :   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE, back);
    4431          354 : }
    4432              : 
    4433              : /* Set the initial value of ASSIGN statement auxiliary variable explicitly.  */
    4434              : 
    4435              : static void
    4436           64 : gfc_trans_assign_aux_var (gfc_symbol * sym, gfc_wrapped_block * block)
    4437              : {
    4438           64 :   stmtblock_t init;
    4439              : 
    4440           64 :   gcc_assert (sym->backend_decl);
    4441           64 :   gfc_start_block (&init);
    4442              : 
    4443              :   /* Set the initial value to length. See the comments in
    4444              :      function gfc_add_assign_aux_vars in this file.  */
    4445           64 :   gfc_add_modify (&init, GFC_DECL_STRING_LEN (sym->backend_decl),
    4446              :                   build_int_cst (gfc_charlen_type_node, -2));
    4447              : 
    4448           64 :   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
    4449           64 : }
    4450              : 
    4451              : static void
    4452       161032 : gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
    4453              : {
    4454       161032 :   tree t = *tp, var, val;
    4455              : 
    4456       161032 :   if (t == NULL || t == error_mark_node)
    4457              :     return;
    4458       151009 :   if (TREE_CONSTANT (t) || DECL_P (t))
    4459              :     return;
    4460              : 
    4461        62056 :   if (TREE_CODE (t) == SAVE_EXPR)
    4462              :     {
    4463        35604 :       if (SAVE_EXPR_RESOLVED_P (t))
    4464              :         {
    4465            0 :           *tp = TREE_OPERAND (t, 0);
    4466            0 :           return;
    4467              :         }
    4468        35604 :       val = TREE_OPERAND (t, 0);
    4469              :     }
    4470              :   else
    4471              :     val = t;
    4472              : 
    4473        62056 :   var = gfc_create_var_np (TREE_TYPE (t), NULL);
    4474        62056 :   gfc_add_decl_to_function (var);
    4475        62056 :   gfc_add_modify (body, var, unshare_expr (val));
    4476        62056 :   if (TREE_CODE (t) == SAVE_EXPR)
    4477        35604 :     TREE_OPERAND (t, 0) = var;
    4478        62056 :   *tp = var;
    4479              : }
    4480              : 
    4481              : static void
    4482        90005 : gfc_trans_vla_type_sizes_1 (tree type, stmtblock_t *body)
    4483              : {
    4484        90005 :   tree t;
    4485              : 
    4486        90005 :   if (type == NULL || type == error_mark_node)
    4487              :     return;
    4488              : 
    4489        90005 :   type = TYPE_MAIN_VARIANT (type);
    4490              : 
    4491        90005 :   if (TREE_CODE (type) == INTEGER_TYPE)
    4492              :     {
    4493        49840 :       gfc_trans_vla_one_sizepos (&TYPE_MIN_VALUE (type), body);
    4494        49840 :       gfc_trans_vla_one_sizepos (&TYPE_MAX_VALUE (type), body);
    4495              : 
    4496        64570 :       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    4497              :         {
    4498        14730 :           TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
    4499        14730 :           TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
    4500              :         }
    4501              :     }
    4502        40165 :   else if (TREE_CODE (type) == ARRAY_TYPE)
    4503              :     {
    4504        30676 :       gfc_trans_vla_type_sizes_1 (TREE_TYPE (type), body);
    4505        30676 :       gfc_trans_vla_type_sizes_1 (TYPE_DOMAIN (type), body);
    4506        30676 :       gfc_trans_vla_one_sizepos (&TYPE_SIZE (type), body);
    4507        30676 :       gfc_trans_vla_one_sizepos (&TYPE_SIZE_UNIT (type), body);
    4508              : 
    4509        30676 :       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    4510              :         {
    4511            0 :           TYPE_SIZE (t) = TYPE_SIZE (type);
    4512            0 :           TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
    4513              :         }
    4514              :     }
    4515              : }
    4516              : 
    4517              : /* Make sure all type sizes and array domains are either constant,
    4518              :    or variable or parameter decls.  This is a simplified variant
    4519              :    of gimplify_type_sizes, but we can't use it here, as none of the
    4520              :    variables in the expressions have been gimplified yet.
    4521              :    As type sizes and domains for various variable length arrays
    4522              :    contain VAR_DECLs that are only initialized at gfc_trans_deferred_vars
    4523              :    time, without this routine gimplify_type_sizes in the middle-end
    4524              :    could result in the type sizes being gimplified earlier than where
    4525              :    those variables are initialized.  */
    4526              : 
    4527              : void
    4528        27161 : gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
    4529              : {
    4530        27161 :   tree type = TREE_TYPE (sym->backend_decl);
    4531              : 
    4532        27161 :   if (TREE_CODE (type) == FUNCTION_TYPE
    4533         1081 :       && (sym->attr.function || sym->attr.result || sym->attr.entry))
    4534              :     {
    4535         1081 :       if (! current_fake_result_decl)
    4536              :         return;
    4537              : 
    4538         1081 :       type = TREE_TYPE (TREE_VALUE (current_fake_result_decl));
    4539              :     }
    4540              : 
    4541        53459 :   while (POINTER_TYPE_P (type))
    4542        26298 :     type = TREE_TYPE (type);
    4543              : 
    4544        27161 :   if (GFC_DESCRIPTOR_TYPE_P (type))
    4545              :     {
    4546         1492 :       tree etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
    4547              : 
    4548         2984 :       while (POINTER_TYPE_P (etype))
    4549         1492 :         etype = TREE_TYPE (etype);
    4550              : 
    4551         1492 :       gfc_trans_vla_type_sizes_1 (etype, body);
    4552              :     }
    4553              : 
    4554        27161 :   gfc_trans_vla_type_sizes_1 (type, body);
    4555              : }
    4556              : 
    4557              : 
    4558              : /* Initialize a derived type by building an lvalue from the symbol
    4559              :    and using trans_assignment to do the work. Set dealloc to false
    4560              :    if no deallocation prior the assignment is needed.  */
    4561              : void
    4562         1452 : gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc,
    4563              :                      bool pdt_ok)
    4564              : {
    4565         1452 :   gfc_expr *e;
    4566         1452 :   tree tmp;
    4567         1452 :   tree present;
    4568              : 
    4569         1452 :   gcc_assert (block);
    4570              : 
    4571              :   /* Initialization of PDTs is done elsewhere.  */
    4572         1452 :   if (IS_PDT (sym) && !pdt_ok)
    4573              :     return;
    4574              : 
    4575         1131 :   gcc_assert (!sym->attr.allocatable);
    4576         1131 :   gfc_set_sym_referenced (sym);
    4577         1131 :   e = gfc_lval_expr_from_sym (sym);
    4578         1131 :   tmp = gfc_trans_assignment (e, sym->value, false, dealloc);
    4579         1131 :   if (sym->attr.dummy && (sym->attr.optional
    4580          241 :                           || sym->ns->proc_name->attr.entry_master))
    4581              :     {
    4582           39 :       present = gfc_conv_expr_present (sym);
    4583           39 :       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
    4584              :                         tmp, build_empty_stmt (input_location));
    4585              :     }
    4586         1131 :   gfc_add_expr_to_block (block, tmp);
    4587         1131 :   gfc_free_expr (e);
    4588              : }
    4589              : 
    4590              : 
    4591              : /* Initialize a PDT, either when the symbol has a value or when all the
    4592              :    components have an initializer.  */
    4593              : static tree
    4594          531 : gfc_init_default_pdt (gfc_symbol *sym, bool dealloc)
    4595              : {
    4596          531 :   stmtblock_t block;
    4597          531 :   tree tmp;
    4598          531 :   gfc_component *c;
    4599              : 
    4600          531 :   if (sym->value && sym->value->symtree
    4601           12 :       && sym->value->symtree->n.sym
    4602           12 :       && !sym->value->symtree->n.sym->attr.artificial)
    4603              :     {
    4604           12 :       tmp = gfc_trans_assignment (gfc_lval_expr_from_sym (sym),
    4605              :                                   sym->value, false, false, true);
    4606           12 :       return tmp;
    4607              :     }
    4608              : 
    4609          519 :   if (!dealloc || !sym->value)
    4610              :     return NULL_TREE;
    4611              : 
    4612              :   /* Allowed in the case where all the components have initializers and
    4613              :      there are no LEN components.  */
    4614          328 :   c = sym->ts.u.derived->components;
    4615          541 :   for (; c; c = c->next)
    4616          521 :     if (c->attr.pdt_len || !c->initializer)
    4617              :       return NULL_TREE;
    4618              : 
    4619           20 :   gfc_init_block (&block);
    4620           20 :   gfc_init_default_dt (sym, &block, dealloc, true);
    4621           20 :   return gfc_finish_block (&block);
    4622              : }
    4623              : 
    4624              : 
    4625              : /* Initialize INTENT(OUT) derived type dummies.  As well as giving
    4626              :    them their default initializer, if they have allocatable
    4627              :    components, they have their allocatable components deallocated.  */
    4628              : 
    4629              : static void
    4630        98202 : init_intent_out_dt (gfc_symbol * proc_sym, gfc_wrapped_block * block)
    4631              : {
    4632        98202 :   stmtblock_t init;
    4633        98202 :   gfc_formal_arglist *f;
    4634        98202 :   tree tmp;
    4635        98202 :   tree present;
    4636        98202 :   gfc_symbol *s;
    4637              : 
    4638        98202 :   gfc_init_block (&init);
    4639       198946 :   for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
    4640       100744 :     if (f->sym && f->sym->attr.intent == INTENT_OUT
    4641         3978 :         && !f->sym->attr.pointer
    4642         3924 :         && f->sym->ts.type == BT_DERIVED)
    4643              :       {
    4644          516 :         s = f->sym;
    4645          516 :         tmp = NULL_TREE;
    4646              : 
    4647              :         /* Note: Allocatables are excluded as they are already handled
    4648              :            by the caller.  */
    4649          516 :         if (!f->sym->attr.allocatable
    4650          516 :             && gfc_is_finalizable (s->ts.u.derived, NULL))
    4651              :           {
    4652           38 :             stmtblock_t block;
    4653           38 :             gfc_expr *e;
    4654              : 
    4655           38 :             gfc_init_block (&block);
    4656           38 :             s->attr.referenced = 1;
    4657           38 :             e = gfc_lval_expr_from_sym (s);
    4658           38 :             gfc_add_finalizer_call (&block, e);
    4659           38 :             gfc_free_expr (e);
    4660           38 :             tmp = gfc_finish_block (&block);
    4661              :           }
    4662              : 
    4663              :         /* Note: Allocatables are excluded as they are already handled
    4664              :            by the caller.  */
    4665          516 :         if (tmp == NULL_TREE && !s->attr.allocatable
    4666          358 :             && s->ts.u.derived->attr.alloc_comp)
    4667          126 :           tmp = gfc_deallocate_alloc_comp (s->ts.u.derived,
    4668              :                                            s->backend_decl,
    4669          126 :                                            s->as ? s->as->rank : 0);
    4670              : 
    4671          516 :         if (tmp != NULL_TREE && (s->attr.optional
    4672          145 :                                  || s->ns->proc_name->attr.entry_master))
    4673              :           {
    4674           19 :             present = gfc_conv_expr_present (s);
    4675           19 :             tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
    4676              :                               present, tmp, build_empty_stmt (input_location));
    4677              :           }
    4678              : 
    4679          516 :         gfc_add_expr_to_block (&init, tmp);
    4680          516 :         if (s->value && !s->attr.allocatable)
    4681          273 :           gfc_init_default_dt (s, &init, false);
    4682              :       }
    4683       100228 :     else if (f->sym && f->sym->attr.intent == INTENT_OUT
    4684         3462 :              && f->sym->ts.type == BT_CLASS
    4685          624 :              && !CLASS_DATA (f->sym)->attr.class_pointer
    4686          605 :              && !CLASS_DATA (f->sym)->attr.allocatable)
    4687              :       {
    4688          400 :         stmtblock_t block;
    4689          400 :         gfc_expr *e;
    4690              : 
    4691          400 :         gfc_init_block (&block);
    4692          400 :         f->sym->attr.referenced = 1;
    4693          400 :         e = gfc_lval_expr_from_sym (f->sym);
    4694          400 :         gfc_add_finalizer_call (&block, e);
    4695          400 :         gfc_free_expr (e);
    4696          400 :         tmp = gfc_finish_block (&block);
    4697              : 
    4698          400 :         if (f->sym->attr.optional || f->sym->ns->proc_name->attr.entry_master)
    4699              :           {
    4700            6 :             present = gfc_conv_expr_present (f->sym);
    4701            6 :             tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
    4702              :                               present, tmp,
    4703              :                               build_empty_stmt (input_location));
    4704              :           }
    4705          400 :         gfc_add_expr_to_block (&init, tmp);
    4706              :       }
    4707        98202 :   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
    4708        98202 : }
    4709              : 
    4710              : 
    4711              : /* Helper function to manage deferred string lengths.  */
    4712              : 
    4713              : static tree
    4714          161 : gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
    4715              :                                 location_t loc)
    4716              : {
    4717          161 :   tree tmp;
    4718              : 
    4719              :   /* Character length passed by reference.  */
    4720          161 :   tmp = sym->ts.u.cl->passed_length;
    4721          161 :   tmp = build_fold_indirect_ref_loc (input_location, tmp);
    4722          161 :   tmp = fold_convert (gfc_charlen_type_node, tmp);
    4723              : 
    4724          161 :   if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
    4725              :     /* Zero the string length when entering the scope.  */
    4726          161 :     gfc_add_modify (init, sym->ts.u.cl->backend_decl,
    4727              :                     build_int_cst (gfc_charlen_type_node, 0));
    4728              :   else
    4729              :     {
    4730            0 :       tree tmp2;
    4731              : 
    4732            0 :       tmp2 = fold_build2_loc (input_location, MODIFY_EXPR,
    4733              :                               gfc_charlen_type_node,
    4734            0 :                               sym->ts.u.cl->backend_decl, tmp);
    4735            0 :       if (sym->attr.optional)
    4736              :         {
    4737            0 :           tree present = gfc_conv_expr_present (sym);
    4738            0 :           tmp2 = build3_loc (input_location, COND_EXPR,
    4739              :                              void_type_node, present, tmp2,
    4740              :                              build_empty_stmt (input_location));
    4741              :         }
    4742            0 :       gfc_add_expr_to_block (init, tmp2);
    4743              :     }
    4744              : 
    4745          161 :   input_location = loc;
    4746              : 
    4747              :   /* Pass the final character length back.  */
    4748          161 :   if (sym->attr.intent != INTENT_IN)
    4749              :     {
    4750          322 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    4751              :                              gfc_charlen_type_node, tmp,
    4752          161 :                              sym->ts.u.cl->backend_decl);
    4753          161 :       if (sym->attr.optional)
    4754              :         {
    4755            0 :           tree present = gfc_conv_expr_present (sym);
    4756            0 :           tmp = build3_loc (input_location, COND_EXPR,
    4757              :                             void_type_node, present, tmp,
    4758              :                             build_empty_stmt (input_location));
    4759              :         }
    4760              :     }
    4761              :   else
    4762              :     tmp = NULL_TREE;
    4763              : 
    4764          161 :   return tmp;
    4765              : }
    4766              : 
    4767              : 
    4768              : /* Get the result expression for a procedure.  */
    4769              : 
    4770              : static tree
    4771        24747 : get_proc_result (gfc_symbol* sym)
    4772              : {
    4773        24747 :   if (sym->attr.subroutine || sym == sym->result)
    4774              :     {
    4775        12453 :       if (current_fake_result_decl != NULL)
    4776        12264 :         return TREE_VALUE (current_fake_result_decl);
    4777              : 
    4778              :       return NULL_TREE;
    4779              :     }
    4780              : 
    4781        12294 :   return sym->result->backend_decl;
    4782              : }
    4783              : 
    4784              : 
    4785              : /* Generate function entry and exit code, and add it to the function body.
    4786              :    This includes:
    4787              :     Allocation and initialization of array variables.
    4788              :     Allocation of character string variables.
    4789              :     Initialization and possibly repacking of dummy arrays.
    4790              :     Initialization of ASSIGN statement auxiliary variable.
    4791              :     Initialization of ASSOCIATE names.
    4792              :     Automatic deallocation.  */
    4793              : 
    4794              : void
    4795        98202 : gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
    4796              : {
    4797        98202 :   location_t loc;
    4798        98202 :   gfc_symbol *sym;
    4799        98202 :   gfc_formal_arglist *f;
    4800        98202 :   stmtblock_t tmpblock;
    4801        98202 :   bool seen_trans_deferred_array = false;
    4802        98202 :   bool is_pdt_type = false;
    4803        98202 :   tree tmp = NULL;
    4804        98202 :   gfc_expr *e;
    4805        98202 :   gfc_se se;
    4806        98202 :   stmtblock_t init;
    4807              : 
    4808              :   /* Deal with implicit return variables.  Explicit return variables will
    4809              :      already have been added.  */
    4810        98202 :   if (gfc_return_by_reference (proc_sym) && proc_sym->result == proc_sym)
    4811              :     {
    4812         1663 :       if (!current_fake_result_decl)
    4813              :         {
    4814           81 :           gfc_entry_list *el = NULL;
    4815           81 :           if (proc_sym->attr.entry_master)
    4816              :             {
    4817           46 :               for (el = proc_sym->ns->entries; el; el = el->next)
    4818           46 :                 if (el->sym != el->sym->result)
    4819              :                   break;
    4820              :             }
    4821              :           /* TODO: move to the appropriate place in resolve.cc.  */
    4822           81 :           if (warn_return_type > 0 && el == NULL)
    4823            4 :             gfc_warning (OPT_Wreturn_type,
    4824              :                          "Return value of function %qs at %L not set",
    4825              :                          proc_sym->name, &proc_sym->declared_at);
    4826              :         }
    4827         1582 :       else if (proc_sym->as)
    4828              :         {
    4829          807 :           tree result = TREE_VALUE (current_fake_result_decl);
    4830          807 :           loc = input_location;
    4831          807 :           input_location = gfc_get_location (&proc_sym->declared_at);
    4832          807 :           gfc_trans_dummy_array_bias (proc_sym, result, block);
    4833              : 
    4834              :           /* An automatic character length, pointer array result.  */
    4835          807 :           if (proc_sym->ts.type == BT_CHARACTER
    4836           69 :               && VAR_P (proc_sym->ts.u.cl->backend_decl))
    4837              :             {
    4838           51 :               tmp = NULL;
    4839           51 :               if (proc_sym->ts.deferred)
    4840              :                 {
    4841           12 :                   gfc_start_block (&init);
    4842           12 :                   tmp = gfc_null_and_pass_deferred_len (proc_sym, &init, loc);
    4843           12 :                   gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
    4844              :                 }
    4845              :               else
    4846           39 :                 gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
    4847              :             }
    4848              :         }
    4849          775 :       else if (proc_sym->ts.type == BT_CHARACTER)
    4850              :         {
    4851          739 :           if (proc_sym->ts.deferred)
    4852              :             {
    4853           91 :               tmp = NULL;
    4854           91 :               loc = input_location;
    4855           91 :               input_location = gfc_get_location (&proc_sym->declared_at);
    4856           91 :               gfc_start_block (&init);
    4857              :               /* Zero the string length on entry.  */
    4858           91 :               gfc_add_modify (&init, proc_sym->ts.u.cl->backend_decl,
    4859              :                               build_int_cst (gfc_charlen_type_node, 0));
    4860              :               /* Null the pointer.  */
    4861           91 :               e = gfc_lval_expr_from_sym (proc_sym);
    4862           91 :               gfc_init_se (&se, NULL);
    4863           91 :               se.want_pointer = 1;
    4864           91 :               gfc_conv_expr (&se, e);
    4865           91 :               gfc_free_expr (e);
    4866           91 :               tmp = se.expr;
    4867           91 :               gfc_add_modify (&init, tmp,
    4868           91 :                               fold_convert (TREE_TYPE (se.expr),
    4869              :                                             null_pointer_node));
    4870           91 :               input_location = loc;
    4871              : 
    4872              :               /* Pass back the string length on exit.  */
    4873           91 :               tmp = proc_sym->ts.u.cl->backend_decl;
    4874           91 :               if (TREE_CODE (tmp) != INDIRECT_REF
    4875           91 :                   && proc_sym->ts.u.cl->passed_length)
    4876              :                 {
    4877           91 :                   tmp = proc_sym->ts.u.cl->passed_length;
    4878           91 :                   tmp = build_fold_indirect_ref_loc (input_location, tmp);
    4879          182 :                   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    4880           91 :                                          TREE_TYPE (tmp), tmp,
    4881           91 :                                          fold_convert
    4882              :                                          (TREE_TYPE (tmp),
    4883              :                                           proc_sym->ts.u.cl->backend_decl));
    4884              :                 }
    4885              :               else
    4886              :                 tmp = NULL_TREE;
    4887              : 
    4888           91 :               gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
    4889              :             }
    4890          648 :           else if (VAR_P (proc_sym->ts.u.cl->backend_decl))
    4891          369 :             gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
    4892              :         }
    4893              :       else
    4894           36 :         gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX);
    4895              :     }
    4896        96539 :   else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
    4897              :     {
    4898              :       /* Nullify explicit return class arrays on entry.  */
    4899           34 :       tree type;
    4900           34 :       tmp = get_proc_result (proc_sym);
    4901           34 :       if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
    4902              :         {
    4903           34 :           gfc_start_block (&init);
    4904           34 :           tmp = gfc_class_data_get (tmp);
    4905           34 :           type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
    4906           34 :           gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
    4907           34 :           gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
    4908              :         }
    4909              :     }
    4910              : 
    4911        98202 :   sym = (proc_sym->attr.function
    4912        98202 :          && proc_sym != proc_sym->result) ? proc_sym->result : NULL;
    4913              : 
    4914         7194 :   if (sym && !sym->attr.allocatable && !sym->attr.pointer
    4915         6570 :       && sym->attr.referenced
    4916        13667 :       && IS_PDT (sym) && !gfc_has_default_initializer (sym->ts.u.derived))
    4917              :     {
    4918            6 :       gfc_init_block (&tmpblock);
    4919            6 :       tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
    4920              :                                    sym->backend_decl,
    4921            6 :                                    sym->as ? sym->as->rank : 0,
    4922            6 :                                    sym->param_list);
    4923            6 :       gfc_add_expr_to_block (&tmpblock, tmp);
    4924            6 :       gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
    4925              :     }
    4926              : 
    4927              :   /* Initialize the INTENT(OUT) derived type dummy arguments.  This
    4928              :      should be done here so that the offsets and lbounds of arrays
    4929              :      are available.  */
    4930        98202 :   loc = input_location;
    4931        98202 :   input_location = gfc_get_location (&proc_sym->declared_at);
    4932        98202 :   init_intent_out_dt (proc_sym, block);
    4933        98202 :   input_location = loc;
    4934              : 
    4935              :   /* For some reasons, internal procedures point to the parent's
    4936              :      namespace.  Top-level procedure and variables inside BLOCK are fine.  */
    4937        98202 :   gfc_namespace *omp_ns = proc_sym->ns;
    4938        98202 :   if (proc_sym->ns->proc_name != proc_sym)
    4939       199197 :     for (omp_ns = proc_sym->ns->contained; omp_ns;
    4940       163098 :          omp_ns = omp_ns->sibling)
    4941       199077 :       if (omp_ns->proc_name == proc_sym)
    4942              :         break;
    4943              : 
    4944              :   /* Add 'omp allocate' attribute for gfc_trans_auto_array_allocation and
    4945              :      unset attr.omp_allocate for 'omp allocate allocator(omp_default_mem_alloc),
    4946              :      which has the normal codepath except for an invalid-use check in the ME.
    4947              :      The main processing happens later in this function.  */
    4948        98202 :   for (struct gfc_omp_namelist *n = omp_ns ? omp_ns->omp_allocate : NULL;
    4949        98257 :        n; n = n->next)
    4950           55 :     if (!TREE_STATIC (n->sym->backend_decl))
    4951              :       {
    4952              :         /* Add empty entries - described and to be filled below.  */
    4953           36 :         tree tmp = build_tree_list (NULL_TREE, NULL_TREE);
    4954           36 :         TREE_CHAIN (tmp) = build_tree_list (NULL_TREE, NULL_TREE);
    4955           36 :         DECL_ATTRIBUTES (n->sym->backend_decl)
    4956           36 :           = tree_cons (get_identifier ("omp allocate"), tmp,
    4957           36 :                                        DECL_ATTRIBUTES (n->sym->backend_decl));
    4958           36 :         if (n->u.align == NULL
    4959           29 :             && n->u2.allocator != NULL
    4960            7 :             && n->u2.allocator->expr_type == EXPR_CONSTANT
    4961            2 :             && mpz_cmp_si (n->u2.allocator->value.integer, 1) == 0)
    4962            1 :           n->sym->attr.omp_allocate = 0;
    4963              :        }
    4964              : 
    4965       172065 :   for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
    4966              :     {
    4967        73863 :       bool alloc_comp_or_fini = (sym->ts.type == BT_DERIVED)
    4968        73863 :                                 && (sym->ts.u.derived->attr.alloc_comp
    4969         5898 :                                     || gfc_is_finalizable (sym->ts.u.derived,
    4970        73863 :                                                            NULL));
    4971        73863 :       if (sym->assoc || sym->attr.vtab)
    4972         5010 :         continue;
    4973              : 
    4974              :       /* Set the vptr of unlimited polymorphic pointer variables so that
    4975              :          they do not cause segfaults in select type, when the selector
    4976              :          is an intrinsic type.  */
    4977        68853 :       if (sym->ts.type == BT_CLASS && UNLIMITED_POLY (sym)
    4978         1029 :           && sym->attr.flavor == FL_VARIABLE && !sym->assoc
    4979         1029 :           && !sym->attr.dummy && CLASS_DATA (sym)->attr.class_pointer)
    4980              :         {
    4981          308 :           gfc_symbol *vtab;
    4982          308 :           gfc_init_block (&tmpblock);
    4983          308 :           vtab = gfc_find_vtab (&sym->ts);
    4984          308 :           if (!vtab->backend_decl)
    4985              :             {
    4986           48 :               if (!vtab->attr.referenced)
    4987            6 :                 gfc_set_sym_referenced (vtab);
    4988           48 :               gfc_get_symbol_decl (vtab);
    4989              :             }
    4990          308 :           tmp = gfc_class_vptr_get (sym->backend_decl);
    4991          308 :           gfc_add_modify (&tmpblock, tmp,
    4992          308 :                           gfc_build_addr_expr (TREE_TYPE (tmp),
    4993              :                                                vtab->backend_decl));
    4994          308 :           gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
    4995              :         }
    4996              : 
    4997        68853 :       if (sym->ts.type == BT_DERIVED
    4998        10561 :           && sym->ts.u.derived
    4999        10561 :           && (sym->ts.u.derived->attr.pdt_type || sym->ts.u.derived->attr.pdt_comp))
    5000              :         {
    5001          683 :           is_pdt_type = true;
    5002          683 :           gfc_init_block (&tmpblock);
    5003              : 
    5004          683 :           if (!sym->attr.dummy && !sym->attr.pointer)
    5005              :             {
    5006          531 :               tmp = gfc_init_default_pdt (sym, true);
    5007          531 :               if (!sym->attr.allocatable && tmp == NULL_TREE)
    5008              :                 {
    5009          397 :                   tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
    5010              :                                                sym->backend_decl,
    5011          397 :                                                sym->as ? sym->as->rank : 0,
    5012          397 :                                                sym->param_list);
    5013          397 :                   gfc_add_expr_to_block (&tmpblock, tmp);
    5014              :                 }
    5015          102 :               else if (tmp != NULL_TREE)
    5016           32 :                 gfc_add_expr_to_block (&tmpblock, tmp);
    5017              : 
    5018          531 :               if (!sym->attr.result && !sym->ts.u.derived->attr.alloc_comp)
    5019          431 :                 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived,
    5020              :                                                sym->backend_decl,
    5021          431 :                                                sym->as ? sym->as->rank : 0);
    5022              :               else
    5023              :                 tmp = NULL_TREE;
    5024              : 
    5025          531 :               gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
    5026              :             }
    5027          152 :           else if (sym->attr.dummy)
    5028              :             {
    5029           62 :               tmp = gfc_check_pdt_dummy (sym->ts.u.derived,
    5030              :                                          sym->backend_decl,
    5031           62 :                                          sym->as ? sym->as->rank : 0,
    5032           62 :                                          sym->param_list);
    5033           62 :               gfc_add_expr_to_block (&tmpblock, tmp);
    5034           62 :               gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
    5035              :             }
    5036              :         }
    5037        68170 :       else if (IS_CLASS_PDT (sym))
    5038              :         {
    5039           12 :           gfc_component *data = CLASS_DATA (sym);
    5040           12 :           is_pdt_type = true;
    5041           12 :           gfc_init_block (&tmpblock);
    5042           12 :           if (!(sym->attr.dummy
    5043           12 :                 || CLASS_DATA (sym)->attr.pointer
    5044           12 :                 || CLASS_DATA (sym)->attr.allocatable))
    5045              :             {
    5046            0 :               tmp = gfc_class_data_get (sym->backend_decl);
    5047            0 :               tmp = gfc_allocate_pdt_comp (data->ts.u.derived, tmp,
    5048            0 :                                            data->as ? data->as->rank : 0,
    5049            0 :                                            sym->param_list);
    5050            0 :               gfc_add_expr_to_block (&tmpblock, tmp);
    5051            0 :               tmp = gfc_class_data_get (sym->backend_decl);
    5052            0 :               if (!sym->attr.result)
    5053            0 :                 tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp,
    5054            0 :                                                data->as ? data->as->rank : 0);
    5055              :               else
    5056              :                 tmp = NULL_TREE;
    5057            0 :               gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
    5058              :             }
    5059           12 :           else if (sym->attr.dummy)
    5060              :             {
    5061            0 :               tmp = gfc_class_data_get (sym->backend_decl);
    5062            0 :               tmp = gfc_check_pdt_dummy (data->ts.u.derived, tmp,
    5063            0 :                                          data->as ? data->as->rank : 0,
    5064            0 :                                          sym->param_list);
    5065            0 :               gfc_add_expr_to_block (&tmpblock, tmp);
    5066            0 :               gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
    5067              :             }
    5068              :         }
    5069              : 
    5070        68853 :       if (sym->ts.type == BT_CLASS
    5071         3791 :           && (sym->attr.save || flag_max_stack_var_size == 0)
    5072           58 :           && CLASS_DATA (sym)->attr.allocatable)
    5073              :         {
    5074           40 :           tree vptr;
    5075              : 
    5076           40 :           if (UNLIMITED_POLY (sym))
    5077            0 :             vptr = null_pointer_node;
    5078              :           else
    5079              :             {
    5080           40 :               gfc_symbol *vsym;
    5081           40 :               vsym = gfc_find_derived_vtab (sym->ts.u.derived);
    5082           40 :               vptr = gfc_get_symbol_decl (vsym);
    5083           40 :               vptr = gfc_build_addr_expr (NULL, vptr);
    5084              :             }
    5085              : 
    5086           40 :           if (CLASS_DATA (sym)->attr.dimension
    5087            8 :               || (CLASS_DATA (sym)->attr.codimension
    5088            1 :                   && flag_coarray != GFC_FCOARRAY_LIB))
    5089              :             {
    5090           33 :               tmp = gfc_class_data_get (sym->backend_decl);
    5091           33 :               tmp = gfc_build_null_descriptor (TREE_TYPE (tmp));
    5092              :             }
    5093              :           else
    5094            7 :             tmp = null_pointer_node;
    5095              : 
    5096           40 :           DECL_INITIAL (sym->backend_decl)
    5097           40 :                 = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp);
    5098           40 :           TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1;
    5099           40 :         }
    5100        68813 :       else if ((sym->attr.dimension || sym->attr.codimension
    5101        12304 :                 || (IS_CLASS_COARRAY_OR_ARRAY (sym)
    5102         1982 :                     && !CLASS_DATA (sym)->attr.allocatable)))
    5103              :         {
    5104        57371 :           bool is_classarray = IS_CLASS_COARRAY_OR_ARRAY (sym);
    5105        57371 :           symbol_attribute *array_attr;
    5106        57371 :           gfc_array_spec *as;
    5107        57371 :           array_type type_of_array;
    5108              : 
    5109        57371 :           array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
    5110        57371 :           as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
    5111              :           /* Assumed-size Cray pointees need to be treated as AS_EXPLICIT.  */
    5112        57371 :           type_of_array = as->type;
    5113        57371 :           if (type_of_array == AS_ASSUMED_SIZE && as->cp_was_assumed)
    5114              :             type_of_array = AS_EXPLICIT;
    5115        57300 :           switch (type_of_array)
    5116              :             {
    5117        37887 :             case AS_EXPLICIT:
    5118        37887 :               if (sym->attr.dummy || sym->attr.result)
    5119         6300 :                 gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
    5120              :               /* Allocatable and pointer arrays need to processed
    5121              :                  explicitly.  */
    5122        31587 :               else if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
    5123        31587 :                        || (sym->ts.type == BT_CLASS
    5124            0 :                            && CLASS_DATA (sym)->attr.class_pointer)
    5125        31587 :                        || array_attr->allocatable)
    5126              :                 {
    5127            0 :                   if (TREE_STATIC (sym->backend_decl))
    5128              :                     {
    5129            0 :                       loc = input_location;
    5130            0 :                       input_location = gfc_get_location (&sym->declared_at);
    5131            0 :                       gfc_trans_static_array_pointer (sym);
    5132            0 :                       input_location = loc;
    5133              :                     }
    5134              :                   else
    5135              :                     {
    5136            0 :                       seen_trans_deferred_array = true;
    5137            0 :                       gfc_trans_deferred_array (sym, block);
    5138              :                     }
    5139              :                 }
    5140        31587 :               else if (sym->attr.codimension
    5141          462 :                        && TREE_STATIC (sym->backend_decl))
    5142              :                 {
    5143          402 :                   gfc_init_block (&tmpblock);
    5144          402 :                   gfc_trans_array_cobounds (TREE_TYPE (sym->backend_decl),
    5145              :                                             &tmpblock, sym);
    5146          402 :                   gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
    5147              :                                         NULL_TREE);
    5148          402 :                   continue;
    5149              :                 }
    5150              :               else
    5151              :                 {
    5152        31185 :                   loc = input_location;
    5153        31185 :                   input_location = gfc_get_location (&sym->declared_at);
    5154              : 
    5155        31185 :                   if (alloc_comp_or_fini)
    5156              :                     {
    5157          503 :                       seen_trans_deferred_array = true;
    5158          503 :                       gfc_trans_deferred_array (sym, block);
    5159              :                     }
    5160        30682 :                   else if (sym->ts.type == BT_DERIVED
    5161         1725 :                              && sym->value
    5162          517 :                              && !sym->attr.data
    5163          491 :                              && sym->attr.save == SAVE_NONE)
    5164              :                     {
    5165          277 :                       gfc_start_block (&tmpblock);
    5166          277 :                       gfc_init_default_dt (sym, &tmpblock, false);
    5167          277 :                       gfc_add_init_cleanup (block,
    5168              :                                             gfc_finish_block (&tmpblock),
    5169              :                                             NULL_TREE);
    5170              :                     }
    5171              : 
    5172        31185 :                   gfc_trans_auto_array_allocation (sym->backend_decl,
    5173              :                                                    sym, block);
    5174        31185 :                   input_location = loc;
    5175              :                 }
    5176              :               break;
    5177              : 
    5178         1521 :             case AS_ASSUMED_SIZE:
    5179              :               /* Must be a dummy parameter.  */
    5180         1521 :               gcc_assert (sym->attr.dummy || as->cp_was_assumed);
    5181              : 
    5182              :               /* We should always pass assumed size arrays the g77 way.  */
    5183         1521 :               if (sym->attr.dummy)
    5184         1521 :                 gfc_trans_g77_array (sym, block);
    5185              :               break;
    5186              : 
    5187         5672 :             case AS_ASSUMED_SHAPE:
    5188              :               /* Must be a dummy parameter.  */
    5189         5672 :               gcc_assert (sym->attr.dummy);
    5190              : 
    5191         5672 :               gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
    5192         5672 :               break;
    5193              : 
    5194        12291 :             case AS_ASSUMED_RANK:
    5195        12291 :             case AS_DEFERRED:
    5196        12291 :               seen_trans_deferred_array = true;
    5197        12291 :               gfc_trans_deferred_array (sym, block);
    5198        12291 :               if (sym->ts.type == BT_CHARACTER && sym->ts.deferred
    5199          748 :                   && sym->attr.result)
    5200              :                 {
    5201           32 :                   gfc_start_block (&init);
    5202           32 :                   loc = input_location;
    5203           32 :                   input_location = gfc_get_location (&sym->declared_at);
    5204           32 :                   tmp = gfc_null_and_pass_deferred_len (sym, &init, loc);
    5205           32 :                   gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
    5206              :                 }
    5207              :               break;
    5208              : 
    5209            0 :             default:
    5210            0 :               gcc_unreachable ();
    5211              :             }
    5212        56969 :           if (alloc_comp_or_fini && !seen_trans_deferred_array)
    5213          276 :             gfc_trans_deferred_array (sym, block);
    5214              :         }
    5215        11442 :       else if ((!sym->attr.dummy || sym->ts.deferred)
    5216        11246 :                 && (sym->ts.type == BT_CLASS
    5217         2889 :                 && CLASS_DATA (sym)->attr.class_pointer))
    5218          523 :         gfc_trans_class_array (sym, block);
    5219        10919 :       else if ((!sym->attr.dummy || sym->ts.deferred)
    5220        10723 :                 && (sym->attr.allocatable
    5221         8397 :                     || (sym->attr.pointer && sym->attr.result)
    5222         8346 :                     || (sym->ts.type == BT_CLASS
    5223         2366 :                         && CLASS_DATA (sym)->attr.allocatable)))
    5224              :         {
    5225              :           /* Ensure that the initialization block may be generated also for
    5226              :              dummy and result variables when -fno-automatic is specified, which
    5227              :              sets flag_max_stack_var_size=0.  */
    5228         4743 :           if (!sym->attr.save
    5229         4664 :               && (flag_max_stack_var_size != 0
    5230            3 :                   || sym->attr.dummy
    5231            3 :                   || sym->attr.result))
    5232              :             {
    5233         4664 :               tree descriptor = NULL_TREE;
    5234              : 
    5235         4664 :               loc = input_location;
    5236         4664 :               input_location = gfc_get_location (&sym->declared_at);
    5237         4664 :               gfc_start_block (&init);
    5238              : 
    5239         4664 :               if (sym->ts.type == BT_CHARACTER
    5240          983 :                   && sym->attr.allocatable
    5241          959 :                   && !sym->attr.dimension
    5242          959 :                   && sym->ts.u.cl && sym->ts.u.cl->length
    5243          191 :                   && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE)
    5244           27 :                 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
    5245              : 
    5246         4664 :               if (!sym->attr.pointer)
    5247              :                 {
    5248              :                   /* Nullify and automatic deallocation of allocatable
    5249              :                      scalars.  */
    5250         4613 :                   e = gfc_lval_expr_from_sym (sym);
    5251         4613 :                   if (sym->ts.type == BT_CLASS)
    5252         2366 :                     gfc_add_data_component (e);
    5253              : 
    5254         4613 :                   gfc_init_se (&se, NULL);
    5255         4613 :                   if (sym->ts.type != BT_CLASS
    5256         2366 :                       || sym->ts.u.derived->attr.dimension
    5257         2366 :                       || sym->ts.u.derived->attr.codimension)
    5258              :                     {
    5259         2247 :                       se.want_pointer = 1;
    5260         2247 :                       gfc_conv_expr (&se, e);
    5261              :                     }
    5262         2366 :                   else if (sym->ts.type == BT_CLASS
    5263         2366 :                            && !CLASS_DATA (sym)->attr.dimension
    5264         1304 :                            && !CLASS_DATA (sym)->attr.codimension)
    5265              :                     {
    5266         1246 :                       se.want_pointer = 1;
    5267         1246 :                       gfc_conv_expr (&se, e);
    5268              :                     }
    5269              :                   else
    5270              :                     {
    5271         1120 :                       se.descriptor_only = 1;
    5272         1120 :                       gfc_conv_expr (&se, e);
    5273         1120 :                       descriptor = se.expr;
    5274         1120 :                       se.expr = gfc_conv_descriptor_data_get (se.expr);
    5275              :                     }
    5276         4613 :                   gfc_free_expr (e);
    5277              : 
    5278         4613 :                   if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
    5279              :                     {
    5280              :                       /* Nullify when entering the scope.  */
    5281         4613 :                       if (sym->ts.type == BT_CLASS
    5282         2366 :                           && (CLASS_DATA (sym)->attr.dimension
    5283         1304 :                               || CLASS_DATA (sym)->attr.codimension))
    5284              :                         {
    5285         1120 :                           stmtblock_t nullify;
    5286         1120 :                           gfc_init_block (&nullify);
    5287         1120 :                           gfc_conv_descriptor_data_set (&nullify, descriptor,
    5288              :                                                         null_pointer_node);
    5289         1120 :                           tmp = gfc_finish_block (&nullify);
    5290         1120 :                         }
    5291              :                       else
    5292              :                         {
    5293         3493 :                           tree typed_null = fold_convert (TREE_TYPE (se.expr),
    5294              :                                                           null_pointer_node);
    5295         3493 :                           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
    5296         3493 :                                                  TREE_TYPE (se.expr), se.expr,
    5297              :                                                  typed_null);
    5298              :                         }
    5299         4613 :                       if (sym->attr.optional)
    5300              :                         {
    5301            0 :                           tree present = gfc_conv_expr_present (sym);
    5302            0 :                           tmp = build3_loc (input_location, COND_EXPR,
    5303              :                                             void_type_node, present, tmp,
    5304              :                                             build_empty_stmt (input_location));
    5305              :                         }
    5306         4613 :                       gfc_add_expr_to_block (&init, tmp);
    5307              :                     }
    5308              :                 }
    5309              : 
    5310         4664 :               if ((sym->attr.dummy || sym->attr.result)
    5311          504 :                     && sym->ts.type == BT_CHARACTER
    5312          117 :                     && sym->ts.deferred
    5313          117 :                     && sym->ts.u.cl->passed_length)
    5314          117 :                 tmp = gfc_null_and_pass_deferred_len (sym, &init, loc);
    5315              :               else
    5316              :                 {
    5317         4547 :                   input_location = loc;
    5318         4547 :                   tmp = NULL_TREE;
    5319              :                 }
    5320              : 
    5321              :               /* Initialize descriptor's TKR information.  */
    5322         4664 :               if (sym->ts.type == BT_CLASS)
    5323         2366 :                 gfc_trans_class_array (sym, block);
    5324              : 
    5325              :               /* Deallocate when leaving the scope. Nullifying is not
    5326              :                  needed.  */
    5327         4664 :               if (!sym->attr.result && !sym->attr.dummy && !sym->attr.pointer
    5328         4160 :                   && !sym->ns->proc_name->attr.is_main_program)
    5329              :                 {
    5330         1385 :                   if (sym->ts.type == BT_CLASS
    5331          471 :                       && CLASS_DATA (sym)->attr.codimension)
    5332            6 :                     tmp = gfc_deallocate_with_status (descriptor, NULL_TREE,
    5333              :                                                       NULL_TREE, NULL_TREE,
    5334              :                                                       NULL_TREE, true, NULL,
    5335              :                                                       GFC_CAF_COARRAY_ANALYZE);
    5336              :                   else
    5337              :                     {
    5338         1379 :                       gfc_expr *expr = gfc_lval_expr_from_sym (sym);
    5339         1379 :                       tmp = gfc_deallocate_scalar_with_status (se.expr,
    5340              :                                                                NULL_TREE,
    5341              :                                                                NULL_TREE,
    5342              :                                                                true, expr,
    5343              :                                                                sym->ts);
    5344         1379 :                       gfc_free_expr (expr);
    5345              :                     }
    5346              :                 }
    5347              : 
    5348         4664 :               if (sym->ts.type == BT_CLASS)
    5349              :                 {
    5350              :                   /* Initialize _vptr to declared type.  */
    5351         2366 :                   loc = input_location;
    5352         2366 :                   input_location = gfc_get_location (&sym->declared_at);
    5353              : 
    5354         2366 :                   e = gfc_lval_expr_from_sym (sym);
    5355         2366 :                   gfc_reset_vptr (&init, e);
    5356         2366 :                   gfc_free_expr (e);
    5357         2366 :                   input_location = loc;
    5358              :                 }
    5359              : 
    5360         4664 :               gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
    5361              :             }
    5362              :         }
    5363         6176 :       else if (sym->ts.type == BT_CHARACTER && sym->ts.deferred)
    5364              :         {
    5365          244 :           tree tmp = NULL;
    5366          244 :           stmtblock_t init;
    5367              : 
    5368              :           /* If we get to here, all that should be left are pointers.  */
    5369          244 :           gcc_assert (sym->attr.pointer);
    5370              : 
    5371          244 :           if (sym->attr.dummy)
    5372              :             {
    5373            0 :               gfc_start_block (&init);
    5374            0 :               loc = input_location;
    5375            0 :               input_location = gfc_get_location (&sym->declared_at);
    5376            0 :               tmp = gfc_null_and_pass_deferred_len (sym, &init, loc);
    5377            0 :               gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
    5378              :             }
    5379          244 :         }
    5380         5932 :       else if (sym->ts.deferred)
    5381            0 :         gfc_fatal_error ("Deferred type parameter not yet supported");
    5382         5932 :       else if (alloc_comp_or_fini)
    5383         4606 :         gfc_trans_deferred_array (sym, block);
    5384         1326 :       else if (sym->ts.type == BT_CHARACTER)
    5385              :         {
    5386          696 :           loc = input_location;
    5387          696 :           input_location = gfc_get_location (&sym->declared_at);
    5388          696 :           if (sym->attr.dummy || sym->attr.result)
    5389          342 :             gfc_trans_dummy_character (sym, sym->ts.u.cl, block);
    5390              :           else
    5391          354 :             gfc_trans_auto_character_variable (sym, block);
    5392          696 :           input_location = loc;
    5393              :         }
    5394          630 :       else if (sym->attr.assign)
    5395              :         {
    5396           64 :           loc = input_location;
    5397           64 :           input_location = gfc_get_location (&sym->declared_at);
    5398           64 :           gfc_trans_assign_aux_var (sym, block);
    5399           64 :           input_location = loc;
    5400              :         }
    5401          566 :       else if (sym->ts.type == BT_DERIVED
    5402          566 :                  && sym->value
    5403          482 :                  && !sym->attr.data
    5404          482 :                  && sym->attr.save == SAVE_NONE)
    5405              :         {
    5406          463 :           gfc_start_block (&tmpblock);
    5407          463 :           gfc_init_default_dt (sym, &tmpblock, false);
    5408          463 :           gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
    5409              :                                 NULL_TREE);
    5410              :         }
    5411          103 :       else if (!(UNLIMITED_POLY(sym)) && !is_pdt_type)
    5412            0 :         gcc_unreachable ();
    5413              :     }
    5414              : 
    5415              :   /* Handle 'omp allocate'. This has to be after the block above as
    5416              :      gfc_add_init_cleanup (..., init, ...) puts 'init' of later calls
    5417              :      before earlier calls.  The code is a bit more complex as gfortran does
    5418              :      not really work with bind expressions / BIND_EXPR_VARS properly, i.e.
    5419              :      gimplify_bind_expr needs some help for placing the GOMP_alloc. Thus,
    5420              :      we pass on the location of the allocate-assignment expression and,
    5421              :      if the size is not constant, the size variable if Fortran computes this
    5422              :      differently. We also might add an expression location after which the
    5423              :      code has to be added, e.g. for character len expressions, which affect
    5424              :      the UNIT_SIZE.  */
    5425        98202 :   gfc_expr *last_allocator = NULL;
    5426        98202 :   if (omp_ns && omp_ns->omp_allocate)
    5427              :     {
    5428           29 :       if (!block->init || TREE_CODE (block->init) != STATEMENT_LIST)
    5429              :         {
    5430           22 :           tree tmp = build1_v (LABEL_EXPR, gfc_build_label_decl (NULL_TREE));
    5431           22 :           append_to_statement_list (tmp, &block->init);
    5432              :         }
    5433           29 :       if (!block->cleanup || TREE_CODE (block->cleanup) != STATEMENT_LIST)
    5434              :         {
    5435           29 :           tree tmp = build1_v (LABEL_EXPR, gfc_build_label_decl (NULL_TREE));
    5436           29 :           append_to_statement_list (tmp, &block->cleanup);
    5437              :         }
    5438              :     }
    5439        98202 :   tree init_stmtlist = block->init;
    5440        98202 :   tree cleanup_stmtlist = block->cleanup;
    5441        98202 :   se.expr = NULL_TREE;
    5442        98202 :   for (struct gfc_omp_namelist *n = omp_ns ? omp_ns->omp_allocate : NULL;
    5443        98257 :        n; n = n->next)
    5444              :     {
    5445           55 :       tree align = (n->u.align ? gfc_conv_constant_to_tree (n->u.align) : NULL_TREE);
    5446           55 :       if (last_allocator != n->u2.allocator)
    5447              :         {
    5448           24 :           location_t loc = input_location;
    5449           24 :           gfc_init_se (&se, NULL);
    5450           24 :           if (n->u2.allocator)
    5451              :             {
    5452           22 :               input_location = gfc_get_location (&n->u2.allocator->where);
    5453           22 :               gfc_conv_expr (&se, n->u2.allocator);
    5454              :             }
    5455              :           /* We need to evalulate non-constants - also to find the location
    5456              :              after which the GOMP_alloc has to be added to - also as BLOCK
    5457              :              does not yield a new BIND_EXPR_BODY.  */
    5458           24 :           if (n->u2.allocator
    5459              :               && (!(CONSTANT_CLASS_P (se.expr) && DECL_P (se.expr))
    5460              :                   || se.pre.head || se.post.head))
    5461              :             {
    5462           22 :               stmtblock_t tmpblock;
    5463           22 :               gfc_init_block (&tmpblock);
    5464           22 :               se.expr = gfc_evaluate_now (se.expr, &tmpblock);
    5465              :               /* First post then pre because the new code is inserted
    5466              :                  at the top. */
    5467           22 :               gfc_add_init_cleanup (block, gfc_finish_block (&se.post), NULL);
    5468           22 :               gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
    5469              :                                     NULL);
    5470           22 :               gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), NULL);
    5471              :             }
    5472           24 :           last_allocator = n->u2.allocator;
    5473           24 :           input_location = loc;
    5474              :         }
    5475           55 :       if (TREE_STATIC (n->sym->backend_decl))
    5476           19 :         continue;
    5477              :       /* 'omp allocate( {purpose: allocator, value: align},
    5478              :                         {purpose: init-stmtlist, value: cleanup-stmtlist},
    5479              :                         {purpose: size-var, value: last-size-expr} )
    5480              :           where init-stmt/cleanup-stmt is the STATEMENT list to find the
    5481              :           try-final block; last-size-expr is to find the location after
    5482              :           which to add the code and 'size-var' is for the proper size, cf.
    5483              :           gfc_trans_auto_array_allocation - either or both of the latter
    5484              :           can be NULL.  */
    5485           36 :       tree tmp = lookup_attribute ("omp allocate",
    5486           36 :                                    DECL_ATTRIBUTES (n->sym->backend_decl));
    5487           36 :       tmp = TREE_VALUE (tmp);
    5488           36 :       TREE_PURPOSE (tmp) = se.expr;
    5489           36 :       TREE_VALUE (tmp) = align;
    5490           36 :       TREE_PURPOSE (TREE_CHAIN (tmp)) = init_stmtlist;
    5491           36 :       TREE_VALUE (TREE_CHAIN (tmp)) = cleanup_stmtlist;
    5492              :     }
    5493              : 
    5494        98202 :   gfc_init_block (&tmpblock);
    5495              : 
    5496       198946 :   for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
    5497              :     {
    5498       100744 :       if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER
    5499         7770 :           && f->sym->ts.u.cl->backend_decl)
    5500              :         {
    5501         7768 :           if (TREE_CODE (f->sym->ts.u.cl->backend_decl) == PARM_DECL)
    5502         4158 :             gfc_trans_vla_type_sizes (f->sym, &tmpblock);
    5503              :         }
    5504              :     }
    5505              : 
    5506       101035 :   if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
    5507        99627 :       && current_fake_result_decl != NULL)
    5508              :     {
    5509          808 :       gcc_assert (proc_sym->ts.u.cl->backend_decl != NULL);
    5510          808 :       if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == PARM_DECL)
    5511           69 :         gfc_trans_vla_type_sizes (proc_sym, &tmpblock);
    5512              :     }
    5513              : 
    5514        98202 :   gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
    5515        98202 : }
    5516              : 
    5517              : 
    5518              : struct module_hasher : ggc_ptr_hash<module_htab_entry>
    5519              : {
    5520              :   typedef const char *compare_type;
    5521              : 
    5522        26412 :   static hashval_t hash (module_htab_entry *s)
    5523              :   {
    5524        26412 :     return htab_hash_string (s->name);
    5525              :   }
    5526              : 
    5527              :   static bool
    5528        31351 :   equal (module_htab_entry *a, const char *b)
    5529              :   {
    5530        31351 :     return !strcmp (a->name, b);
    5531              :   }
    5532              : };
    5533              : 
    5534              : static GTY (()) hash_table<module_hasher> *module_htab;
    5535              : 
    5536              : /* Hash and equality functions for module_htab's decls.  */
    5537              : 
    5538              : hashval_t
    5539       175439 : module_decl_hasher::hash (tree t)
    5540              : {
    5541       175439 :   const_tree n = DECL_NAME (t);
    5542       175439 :   if (n == NULL_TREE)
    5543        25660 :     n = TYPE_NAME (TREE_TYPE (t));
    5544       175439 :   return htab_hash_string (IDENTIFIER_POINTER (n));
    5545              : }
    5546              : 
    5547              : bool
    5548       182681 : module_decl_hasher::equal (tree t1, const char *x2)
    5549              : {
    5550       182681 :   const_tree n1 = DECL_NAME (t1);
    5551       182681 :   if (n1 == NULL_TREE)
    5552        25949 :     n1 = TYPE_NAME (TREE_TYPE (t1));
    5553       182681 :   return strcmp (IDENTIFIER_POINTER (n1), x2) == 0;
    5554              : }
    5555              : 
    5556              : struct module_htab_entry *
    5557        29610 : gfc_find_module (const char *name)
    5558              : {
    5559        29610 :   if (! module_htab)
    5560         8067 :     module_htab = hash_table<module_hasher>::create_ggc (10);
    5561              : 
    5562        29610 :   module_htab_entry **slot
    5563        29610 :     = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
    5564        29610 :   if (*slot == NULL)
    5565              :     {
    5566        10289 :       module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
    5567              : 
    5568        10289 :       entry->name = gfc_get_string ("%s", name);
    5569        10289 :       entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
    5570        10289 :       *slot = entry;
    5571              :     }
    5572        29610 :   return *slot;
    5573              : }
    5574              : 
    5575              : void
    5576        53265 : gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
    5577              : {
    5578        53265 :   const char *name;
    5579              : 
    5580        53265 :   if (DECL_NAME (decl))
    5581        45292 :     name = IDENTIFIER_POINTER (DECL_NAME (decl));
    5582              :   else
    5583              :     {
    5584         7973 :       gcc_assert (TREE_CODE (decl) == TYPE_DECL);
    5585         7973 :       name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
    5586              :     }
    5587        53265 :   tree *slot
    5588        53265 :     = entry->decls->find_slot_with_hash (name, htab_hash_string (name),
    5589              :                                          INSERT);
    5590        53265 :   if (*slot == NULL)
    5591        53253 :     *slot = decl;
    5592        53265 : }
    5593              : 
    5594              : 
    5595              : /* Generate debugging symbols for namelists. This function must come after
    5596              :    generate_local_decl to ensure that the variables in the namelist are
    5597              :    already declared.  */
    5598              : 
    5599              : static tree
    5600          743 : generate_namelist_decl (gfc_symbol * sym)
    5601              : {
    5602          743 :   gfc_namelist *nml;
    5603          743 :   tree decl;
    5604          743 :   vec<constructor_elt, va_gc> *nml_decls = NULL;
    5605              : 
    5606          743 :   gcc_assert (sym->attr.flavor == FL_NAMELIST);
    5607         2745 :   for (nml = sym->namelist; nml; nml = nml->next)
    5608              :     {
    5609         2002 :       if (nml->sym->backend_decl == NULL_TREE)
    5610              :         {
    5611          220 :           nml->sym->attr.referenced = 1;
    5612          220 :           nml->sym->backend_decl = gfc_get_symbol_decl (nml->sym);
    5613              :         }
    5614         2002 :       DECL_IGNORED_P (nml->sym->backend_decl) = 0;
    5615         2002 :       CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
    5616              :     }
    5617              : 
    5618          743 :   decl = make_node (NAMELIST_DECL);
    5619          743 :   TREE_TYPE (decl) = void_type_node;
    5620          743 :   NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
    5621          743 :   DECL_NAME (decl) = get_identifier (sym->name);
    5622          743 :   return decl;
    5623              : }
    5624              : 
    5625              : 
    5626              : /* Output an initialized decl for a module variable.  */
    5627              : 
    5628              : static void
    5629       142360 : gfc_create_module_variable (gfc_symbol * sym)
    5630              : {
    5631       142360 :   tree decl;
    5632              : 
    5633              :   /* Module functions with alternate entries are dealt with later and
    5634              :      would get caught by the next condition.  */
    5635       142360 :   if (sym->attr.entry)
    5636              :     return;
    5637              : 
    5638              :   /* Make sure we convert the types of the derived types from iso_c_binding
    5639              :      into (void *).  */
    5640       141879 :   if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
    5641        31284 :       && sym->ts.type == BT_DERIVED)
    5642         1442 :     sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
    5643              : 
    5644       141879 :   if (gfc_fl_struct (sym->attr.flavor)
    5645        22871 :       && sym->backend_decl
    5646         8007 :       && TREE_CODE (sym->backend_decl) == RECORD_TYPE)
    5647              :     {
    5648         7973 :       decl = sym->backend_decl;
    5649         7973 :       gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
    5650              : 
    5651         7973 :       if (!sym->attr.use_assoc && !sym->attr.used_in_submodule)
    5652              :         {
    5653         7876 :           gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE
    5654              :                       || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl);
    5655         7876 :           gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE
    5656              :                       || DECL_CONTEXT (TYPE_STUB_DECL (decl))
    5657              :                            == sym->ns->proc_name->backend_decl);
    5658              :         }
    5659         7973 :       TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
    5660         7973 :       DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl;
    5661         7973 :       gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl));
    5662              :     }
    5663              : 
    5664              :   /* Only output variables, procedure pointers and array valued,
    5665              :      or derived type, parameters.  */
    5666       141879 :   if (sym->attr.flavor != FL_VARIABLE
    5667       119582 :         && !(sym->attr.flavor == FL_PARAMETER
    5668        39381 :                && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
    5669       118542 :         && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer))
    5670              :     return;
    5671              : 
    5672        23410 :   if ((sym->attr.in_common || sym->attr.in_equivalence) && sym->backend_decl)
    5673              :     {
    5674          461 :       decl = sym->backend_decl;
    5675          461 :       gcc_assert (DECL_FILE_SCOPE_P (decl));
    5676          461 :       gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
    5677          461 :       DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
    5678          461 :       gfc_module_add_decl (cur_module, decl);
    5679              :     }
    5680              : 
    5681              :   /* Don't generate variables from other modules. Variables from
    5682              :      COMMONs and Cray pointees will already have been generated.  */
    5683        23410 :   if (sym->attr.use_assoc || sym->attr.used_in_submodule
    5684        19706 :       || sym->attr.in_common || sym->attr.cray_pointee)
    5685              :     return;
    5686              : 
    5687              :   /* Equivalenced variables arrive here after creation.  */
    5688        19387 :   if (sym->backend_decl
    5689          581 :       && (sym->equiv_built || sym->attr.in_equivalence))
    5690              :     return;
    5691              : 
    5692        19300 :   if (sym->backend_decl && !sym->attr.vtab && !sym->attr.target)
    5693            0 :     gfc_internal_error ("backend decl for module variable %qs already exists",
    5694              :                         sym->name);
    5695              : 
    5696        19300 :   if (sym->module && !sym->attr.result && !sym->attr.dummy
    5697        19300 :       && (sym->attr.access == ACCESS_UNKNOWN
    5698         3698 :           && (sym->ns->default_access == ACCESS_PRIVATE
    5699         3408 :               || (sym->ns->default_access == ACCESS_UNKNOWN
    5700         3394 :                   && flag_module_private))))
    5701          291 :     sym->attr.access = ACCESS_PRIVATE;
    5702              : 
    5703        19300 :   if (warn_unused_variable && !sym->attr.referenced
    5704          138 :       && sym->attr.access == ACCESS_PRIVATE)
    5705            3 :     gfc_warning (OPT_Wunused_value,
    5706              :                  "Unused PRIVATE module variable %qs declared at %L",
    5707              :                  sym->name, &sym->declared_at);
    5708              : 
    5709              :   /* We always want module variables to be created.  */
    5710        19300 :   sym->attr.referenced = 1;
    5711              :   /* Create the decl.  */
    5712        19300 :   decl = gfc_get_symbol_decl (sym);
    5713              : 
    5714              :   /* Create the variable.  */
    5715        19300 :   pushdecl (decl);
    5716        19300 :   gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
    5717              :               || ((sym->ns->parent->proc_name->attr.flavor == FL_MODULE
    5718              :                    || sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE)
    5719              :                   && sym->fn_result_spec));
    5720        19300 :   DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
    5721        19300 :   rest_of_decl_compilation (decl, 1, 0);
    5722        19300 :   gfc_module_add_decl (cur_module, decl);
    5723              : 
    5724              :   /* Also add length of strings.  */
    5725        19300 :   if (sym->ts.type == BT_CHARACTER)
    5726              :     {
    5727          400 :       tree length;
    5728              : 
    5729          400 :       length = sym->ts.u.cl->backend_decl;
    5730          400 :       gcc_assert (length || sym->attr.proc_pointer);
    5731          399 :       if (length && !INTEGER_CST_P (length))
    5732              :         {
    5733           54 :           pushdecl (length);
    5734           54 :           rest_of_decl_compilation (length, 1, 0);
    5735              :         }
    5736              :     }
    5737              : 
    5738        19300 :   if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
    5739           26 :       && sym->attr.referenced && !sym->attr.use_assoc)
    5740           26 :     has_coarray_vars_or_accessors = true;
    5741              : }
    5742              : 
    5743              : /* Emit debug information for USE statements.  */
    5744              : 
    5745              : static void
    5746        93338 : gfc_trans_use_stmts (gfc_namespace * ns)
    5747              : {
    5748        93338 :   gfc_use_list *use_stmt;
    5749       104892 :   for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next)
    5750              :     {
    5751        11554 :       struct module_htab_entry *entry
    5752        11554 :         = gfc_find_module (use_stmt->module_name);
    5753        11554 :       gfc_use_rename *rent;
    5754              : 
    5755        11554 :       if (entry->namespace_decl == NULL)
    5756              :         {
    5757         1262 :           entry->namespace_decl
    5758         1262 :             = build_decl (input_location,
    5759              :                           NAMESPACE_DECL,
    5760              :                           get_identifier (use_stmt->module_name),
    5761              :                           void_type_node);
    5762         1262 :           DECL_EXTERNAL (entry->namespace_decl) = 1;
    5763              :         }
    5764        11554 :       input_location = gfc_get_location (&use_stmt->where);
    5765        11554 :       if (!use_stmt->only_flag)
    5766        10012 :         (*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
    5767              :                                                  NULL_TREE,
    5768        10012 :                                                  ns->proc_name->backend_decl,
    5769              :                                                  false, false);
    5770        14146 :       for (rent = use_stmt->rename; rent; rent = rent->next)
    5771              :         {
    5772         2592 :           tree decl, local_name;
    5773              : 
    5774         2592 :           if (rent->op != INTRINSIC_NONE)
    5775          104 :             continue;
    5776              : 
    5777         2488 :                                                  hashval_t hash = htab_hash_string (rent->use_name);
    5778         2488 :           tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
    5779              :                                                           INSERT);
    5780         2488 :           if (*slot == NULL)
    5781              :             {
    5782         1382 :               gfc_symtree *st;
    5783              : 
    5784         1382 :               st = gfc_find_symtree (ns->sym_root,
    5785         1382 :                                      rent->local_name[0]
    5786              :                                      ? rent->local_name : rent->use_name);
    5787              : 
    5788              :               /* The following can happen if a derived type is renamed.  */
    5789         1382 :               if (!st)
    5790              :                 {
    5791            0 :                   char *name;
    5792            0 :                   name = xstrdup (rent->local_name[0]
    5793              :                                   ? rent->local_name : rent->use_name);
    5794            0 :                   name[0] = (char) TOUPPER ((unsigned char) name[0]);
    5795            0 :                   st = gfc_find_symtree (ns->sym_root, name);
    5796            0 :                   free (name);
    5797            0 :                   gcc_assert (st);
    5798              :                 }
    5799              : 
    5800              :               /* Sometimes, generic interfaces wind up being over-ruled by a
    5801              :                  local symbol (see PR41062).  */
    5802         1382 :               if (!st->n.sym->attr.use_assoc)
    5803              :                 {
    5804            2 :                   *slot = error_mark_node;
    5805            2 :                   entry->decls->clear_slot (slot);
    5806            2 :                   continue;
    5807              :                 }
    5808              : 
    5809         1380 :               if (st->n.sym->backend_decl
    5810          163 :                   && DECL_P (st->n.sym->backend_decl)
    5811          163 :                   && st->n.sym->module
    5812          163 :                   && strcmp (st->n.sym->module, use_stmt->module_name) == 0)
    5813              :                 {
    5814          154 :                   gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
    5815              :                               || !VAR_P (st->n.sym->backend_decl));
    5816          154 :                   decl = copy_node (st->n.sym->backend_decl);
    5817          154 :                   DECL_CONTEXT (decl) = entry->namespace_decl;
    5818          154 :                   DECL_EXTERNAL (decl) = 1;
    5819          154 :                   DECL_IGNORED_P (decl) = 0;
    5820          154 :                   DECL_INITIAL (decl) = NULL_TREE;
    5821              :                 }
    5822         1226 :               else if (st->n.sym->attr.flavor == FL_NAMELIST
    5823            0 :                        && st->n.sym->attr.use_only
    5824            0 :                        && st->n.sym->module
    5825            0 :                        && strcmp (st->n.sym->module, use_stmt->module_name)
    5826              :                           == 0)
    5827              :                 {
    5828            0 :                   decl = generate_namelist_decl (st->n.sym);
    5829            0 :                   DECL_CONTEXT (decl) = entry->namespace_decl;
    5830            0 :                   DECL_EXTERNAL (decl) = 1;
    5831            0 :                   DECL_IGNORED_P (decl) = 0;
    5832            0 :                   DECL_INITIAL (decl) = NULL_TREE;
    5833              :                 }
    5834              :               else
    5835              :                 {
    5836         1226 :                   *slot = error_mark_node;
    5837         1226 :                   entry->decls->clear_slot (slot);
    5838         1226 :                   continue;
    5839              :                 }
    5840          154 :               *slot = decl;
    5841              :             }
    5842         1260 :           decl = (tree) *slot;
    5843         1260 :           if (rent->local_name[0])
    5844          198 :             local_name = get_identifier (rent->local_name);
    5845              :           else
    5846              :             local_name = NULL_TREE;
    5847         1260 :           input_location = gfc_get_location (&rent->where);
    5848         1260 :           (*debug_hooks->imported_module_or_decl) (decl, local_name,
    5849         1260 :                                                    ns->proc_name->backend_decl,
    5850         1260 :                                                    !use_stmt->only_flag,
    5851              :                                                    false);
    5852              :         }
    5853              :     }
    5854        93338 : }
    5855              : 
    5856              : 
    5857              : /* Return true if expr is a constant initializer that gfc_conv_initializer
    5858              :    will handle.  */
    5859              : 
    5860              : static bool
    5861        23147 : check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
    5862              :                             bool pointer)
    5863              : {
    5864        23147 :   gfc_constructor *c;
    5865        23147 :   gfc_component *cm;
    5866              : 
    5867        23147 :   if (pointer)
    5868              :     return true;
    5869        23143 :   else if (array)
    5870              :     {
    5871         2571 :       if (expr->expr_type == EXPR_CONSTANT || expr->expr_type == EXPR_NULL)
    5872              :         return true;
    5873         2543 :       else if (expr->expr_type == EXPR_STRUCTURE)
    5874           12 :         return check_constant_initializer (expr, ts, false, false);
    5875         2531 :       else if (expr->expr_type != EXPR_ARRAY)
    5876              :         return false;
    5877         2531 :       for (c = gfc_constructor_first (expr->value.constructor);
    5878       134041 :            c; c = gfc_constructor_next (c))
    5879              :         {
    5880       131510 :           if (c->iterator)
    5881              :             return false;
    5882       131510 :           if (c->expr->expr_type == EXPR_STRUCTURE)
    5883              :             {
    5884          283 :               if (!check_constant_initializer (c->expr, ts, false, false))
    5885              :                 return false;
    5886              :             }
    5887       131227 :           else if (c->expr->expr_type != EXPR_CONSTANT)
    5888              :             return false;
    5889              :         }
    5890              :       return true;
    5891              :     }
    5892        20572 :   else switch (ts->type)
    5893              :     {
    5894          440 :     case_bt_struct:
    5895          440 :       if (expr->expr_type != EXPR_STRUCTURE)
    5896              :         return false;
    5897          440 :       cm = expr->ts.u.derived->components;
    5898          440 :       for (c = gfc_constructor_first (expr->value.constructor);
    5899         1003 :            c; c = gfc_constructor_next (c), cm = cm->next)
    5900              :         {
    5901          571 :           if (!c->expr || cm->attr.allocatable)
    5902           14 :             continue;
    5903          557 :           if (!check_constant_initializer (c->expr, &cm->ts,
    5904              :                                            cm->attr.dimension,
    5905              :                                            cm->attr.pointer))
    5906              :             return false;
    5907              :         }
    5908              :       return true;
    5909        20132 :     default:
    5910        20132 :       return expr->expr_type == EXPR_CONSTANT;
    5911              :     }
    5912              : }
    5913              : 
    5914              : /* Emit debug info for parameters and unreferenced variables with
    5915              :    initializers.  */
    5916              : 
    5917              : static void
    5918      1199361 : gfc_emit_parameter_debug_info (gfc_symbol *sym)
    5919              : {
    5920      1199361 :   tree decl;
    5921              : 
    5922      1199361 :   if (sym->attr.flavor != FL_PARAMETER
    5923       953543 :       && (sym->attr.flavor != FL_VARIABLE || sym->attr.referenced))
    5924              :     return;
    5925              : 
    5926       284201 :   if (sym->backend_decl != NULL
    5927       262396 :       || sym->value == NULL
    5928       233530 :       || sym->attr.use_assoc
    5929        22355 :       || sym->attr.dummy
    5930        22355 :       || sym->attr.result
    5931        22355 :       || sym->attr.function
    5932        22355 :       || sym->attr.intrinsic
    5933        22355 :       || sym->attr.pointer
    5934        22345 :       || sym->attr.allocatable
    5935        22345 :       || sym->attr.cray_pointee
    5936        22345 :       || sym->attr.threadprivate
    5937        22344 :       || sym->attr.is_bind_c
    5938        22344 :       || sym->attr.subref_array_pointer
    5939        22344 :       || sym->attr.assign)
    5940              :     return;
    5941              : 
    5942        22344 :   if (sym->ts.type == BT_CHARACTER)
    5943              :     {
    5944         1337 :       gfc_conv_const_charlen (sym->ts.u.cl);
    5945         1337 :       if (sym->ts.u.cl->backend_decl == NULL
    5946         1337 :           || TREE_CODE (sym->ts.u.cl->backend_decl) != INTEGER_CST)
    5947              :         return;
    5948              :     }
    5949        21007 :   else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp)
    5950              :     return;
    5951              : 
    5952        22295 :   if (sym->as)
    5953              :     {
    5954         2506 :       int n;
    5955              : 
    5956         2506 :       if (sym->as->type != AS_EXPLICIT)
    5957              :         return;
    5958         5654 :       for (n = 0; n < sym->as->rank; n++)
    5959         3148 :         if (sym->as->lower[n]->expr_type != EXPR_CONSTANT
    5960         3148 :             || sym->as->upper[n] == NULL
    5961         3148 :             || sym->as->upper[n]->expr_type != EXPR_CONSTANT)
    5962              :           return;
    5963              :     }
    5964              : 
    5965        22295 :   if (!check_constant_initializer (sym->value, &sym->ts,
    5966        22295 :                                    sym->attr.dimension, false))
    5967              :     return;
    5968              : 
    5969        22286 :   if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
    5970              :     return;
    5971              : 
    5972              :   /* Create the decl for the variable or constant.  */
    5973        44572 :   decl = build_decl (input_location,
    5974        22286 :                      sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
    5975              :                      gfc_sym_identifier (sym), gfc_sym_type (sym));
    5976        22286 :   if (sym->attr.flavor == FL_PARAMETER)
    5977        22057 :     TREE_READONLY (decl) = 1;
    5978        22286 :   gfc_set_decl_location (decl, &sym->declared_at);
    5979        22286 :   if (sym->attr.dimension)
    5980         2506 :     GFC_DECL_PACKED_ARRAY (decl) = 1;
    5981        22286 :   DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
    5982        22286 :   TREE_STATIC (decl) = 1;
    5983        22286 :   TREE_USED (decl) = 1;
    5984        22286 :   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
    5985         2482 :     TREE_PUBLIC (decl) = 1;
    5986        22286 :   DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
    5987        22286 :                                               TREE_TYPE (decl),
    5988        22286 :                                               sym->attr.dimension,
    5989              :                                               false, false);
    5990        22286 :   debug_hooks->early_global_decl (decl);
    5991              : }
    5992              : 
    5993              : 
    5994              : static void
    5995         6683 : generate_coarray_sym_init (gfc_symbol *sym)
    5996              : {
    5997         6683 :   tree tmp, size, decl, token, desc;
    5998         6683 :   bool is_lock_type, is_event_type;
    5999         6683 :   int reg_type;
    6000         6683 :   gfc_se se;
    6001         6683 :   symbol_attribute attr;
    6002              : 
    6003         6683 :   if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
    6004          395 :       || sym->attr.use_assoc || !sym->attr.referenced
    6005          391 :       || sym->attr.associate_var
    6006          340 :       || sym->attr.select_type_temporary)
    6007         6343 :     return;
    6008              : 
    6009          340 :   decl = sym->backend_decl;
    6010          340 :   TREE_USED(decl) = 1;
    6011          340 :   gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
    6012              : 
    6013          680 :   is_lock_type = sym->ts.type == BT_DERIVED
    6014          152 :                  && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
    6015          374 :                  && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE;
    6016              : 
    6017          680 :   is_event_type = sym->ts.type == BT_DERIVED
    6018          152 :                   && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
    6019          374 :                   && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE;
    6020              : 
    6021              :   /* FIXME: Workaround for PR middle-end/49106, cf. also PR middle-end/49108
    6022              :      to make sure the variable is not optimized away.  */
    6023          340 :   DECL_PRESERVE_P (DECL_CONTEXT (decl)) = 1;
    6024              : 
    6025              :   /* For lock types, we pass the array size as only the library knows the
    6026              :      size of the variable.  */
    6027          340 :   if (is_lock_type || is_event_type)
    6028           34 :     size = gfc_index_one_node;
    6029              :   else
    6030          306 :     size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (decl)));
    6031              : 
    6032              :   /* Ensure that we do not have size=0 for zero-sized arrays.  */
    6033          340 :   size = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
    6034              :                           fold_convert (size_type_node, size),
    6035              :                           build_int_cst (size_type_node, 1));
    6036              : 
    6037          340 :   if (GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)))
    6038              :     {
    6039          109 :       tmp = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (decl));
    6040          109 :       size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
    6041              :                               fold_convert (size_type_node, tmp), size);
    6042              :     }
    6043              : 
    6044          340 :   gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (decl)) != NULL_TREE);
    6045         1020 :   token = gfc_build_addr_expr (ppvoid_type_node,
    6046          340 :                                GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE(decl)));
    6047          340 :   if (is_lock_type)
    6048           29 :     reg_type = sym->attr.artificial ? GFC_CAF_CRITICAL : GFC_CAF_LOCK_STATIC;
    6049          311 :   else if (is_event_type)
    6050              :     reg_type = GFC_CAF_EVENT_STATIC;
    6051              :   else
    6052          306 :     reg_type = GFC_CAF_COARRAY_STATIC;
    6053              : 
    6054              :   /* Compile the symbol attribute.  */
    6055          340 :   if (sym->ts.type == BT_CLASS)
    6056              :     {
    6057            0 :       attr = CLASS_DATA (sym)->attr;
    6058              :       /* The pointer attribute is always set on classes, overwrite it with the
    6059              :          class_pointer attribute, which denotes the pointer for classes.  */
    6060            0 :       attr.pointer = attr.class_pointer;
    6061              :     }
    6062              :   else
    6063          340 :     attr = sym->attr;
    6064          340 :   gfc_init_se (&se, NULL);
    6065          340 :   desc = gfc_conv_scalar_to_descriptor (&se, decl, attr);
    6066          340 :   gfc_add_block_to_block (&caf_init_block, &se.pre);
    6067              : 
    6068          340 :   tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 7, size,
    6069          340 :                              build_int_cst (integer_type_node, reg_type),
    6070              :                              token, gfc_build_addr_expr (pvoid_type_node, desc),
    6071              :                              null_pointer_node, /* stat.  */
    6072              :                              null_pointer_node, /* errgmsg.  */
    6073              :                              build_zero_cst (size_type_node)); /* errmsg_len.  */
    6074          340 :   gfc_add_expr_to_block (&caf_init_block, tmp);
    6075          340 :   gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl),
    6076              :                                           gfc_conv_descriptor_data_get (desc)));
    6077              : 
    6078              :   /* Handle "static" initializer.  */
    6079          340 :   if (sym->value)
    6080              :     {
    6081          106 :       if (sym->value->expr_type == EXPR_ARRAY)
    6082              :         {
    6083           12 :           gfc_constructor *c, *cnext;
    6084              : 
    6085              :           /* Test if the array has more than one element.  */
    6086           12 :           c = gfc_constructor_first (sym->value->value.constructor);
    6087           12 :           gcc_assert (c);  /* Empty constructor should not happen here.  */
    6088           12 :           cnext = gfc_constructor_next (c);
    6089              : 
    6090           12 :           if (cnext)
    6091              :             {
    6092              :               /* An EXPR_ARRAY with a rank > 1 here has to come from a
    6093              :                  DATA statement.  Set its rank here as not to confuse
    6094              :                  the following steps.   */
    6095           11 :               sym->value->rank = 1;
    6096              :             }
    6097              :           else
    6098              :             {
    6099              :               /* There is only a single value in the constructor, use
    6100              :                  it directly for the assignment.  */
    6101            1 :               gfc_expr *new_expr;
    6102            1 :               new_expr = gfc_copy_expr (c->expr);
    6103            1 :               gfc_free_expr (sym->value);
    6104            1 :               sym->value = new_expr;
    6105              :             }
    6106              :         }
    6107              : 
    6108          106 :       sym->attr.pointer = 1;
    6109          106 :       tmp = gfc_trans_assignment (gfc_lval_expr_from_sym (sym), sym->value,
    6110              :                                   true, false);
    6111          106 :       sym->attr.pointer = 0;
    6112          106 :       gfc_add_expr_to_block (&caf_init_block, tmp);
    6113              :     }
    6114          234 :   else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pointer_comp)
    6115              :     {
    6116           32 :       tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, decl, sym->as
    6117              :                                     ? sym->as->rank : 0,
    6118              :                                     GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
    6119           32 :       gfc_add_expr_to_block (&caf_init_block, tmp);
    6120              :     }
    6121              : }
    6122              : 
    6123              : struct caf_accessor
    6124              : {
    6125              :   struct caf_accessor *next;
    6126              :   gfc_expr *hash, *fdecl;
    6127              : };
    6128              : 
    6129              : static struct caf_accessor *caf_accessor_head = NULL;
    6130              : 
    6131              : void
    6132         1488 : gfc_add_caf_accessor (gfc_expr *h, gfc_expr *f)
    6133              : {
    6134         1488 :   struct caf_accessor *n = XCNEW (struct caf_accessor);
    6135         1488 :   n->next = caf_accessor_head;
    6136         1488 :   n->hash = h;
    6137         1488 :   n->fdecl = f;
    6138         1488 :   caf_accessor_head = n;
    6139         1488 : }
    6140              : 
    6141              : void
    6142          459 : create_caf_accessor_register (stmtblock_t *block)
    6143              : {
    6144          459 :   gfc_se se;
    6145          459 :   tree hash, fdecl;
    6146          459 :   gfc_init_se (&se, NULL);
    6147         1887 :   for (struct caf_accessor *curr = caf_accessor_head; curr;)
    6148              :     {
    6149         1428 :       gfc_conv_expr (&se, curr->hash);
    6150         1428 :       hash = se.expr;
    6151         1428 :       gfc_conv_expr (&se, curr->fdecl);
    6152         1428 :       fdecl = se.expr;
    6153         1428 :       TREE_USED (fdecl) = 1;
    6154         1428 :       TREE_STATIC (fdecl) = 1;
    6155         1428 :       gcc_assert (FUNCTION_POINTER_TYPE_P (TREE_TYPE (fdecl)));
    6156         1428 :       gfc_add_expr_to_block (
    6157              :         block, build_call_expr (gfor_fndecl_caf_register_accessor, 2, hash,
    6158              :                                 /*gfc_build_addr_expr (NULL_TREE,*/ fdecl));
    6159         1428 :       curr = curr->next;
    6160         1428 :       free (caf_accessor_head);
    6161         1428 :       caf_accessor_head = curr;
    6162              :     }
    6163          459 :   gfc_add_expr_to_block (
    6164              :     block, build_call_expr (gfor_fndecl_caf_register_accessors_finish, 0));
    6165          459 : }
    6166              : 
    6167              : /* Generate constructor function to initialize static, nonallocatable
    6168              :    coarrays.  */
    6169              : 
    6170              : static void
    6171          459 : generate_coarray_init (gfc_namespace *ns)
    6172              : {
    6173          459 :   tree fndecl, tmp, decl, save_fn_decl;
    6174              : 
    6175          459 :   save_fn_decl = current_function_decl;
    6176          459 :   push_function_context ();
    6177              : 
    6178          459 :   tmp = build_function_type_list (void_type_node, NULL_TREE);
    6179          459 :   fndecl = build_decl (input_location, FUNCTION_DECL,
    6180              :                        create_tmp_var_name ("_caf_init"), tmp);
    6181              : 
    6182          459 :   DECL_STATIC_CONSTRUCTOR (fndecl) = 1;
    6183          459 :   SET_DECL_INIT_PRIORITY (fndecl, DEFAULT_INIT_PRIORITY);
    6184              : 
    6185          459 :   decl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node);
    6186          459 :   DECL_ARTIFICIAL (decl) = 1;
    6187          459 :   DECL_IGNORED_P (decl) = 1;
    6188          459 :   DECL_CONTEXT (decl) = fndecl;
    6189          459 :   DECL_RESULT (fndecl) = decl;
    6190              : 
    6191          459 :   pushdecl (fndecl);
    6192          459 :   current_function_decl = fndecl;
    6193          459 :   announce_function (fndecl);
    6194              : 
    6195          459 :   rest_of_decl_compilation (fndecl, 0, 0);
    6196          459 :   make_decl_rtl (fndecl);
    6197          459 :   allocate_struct_function (fndecl, false);
    6198              : 
    6199          459 :   pushlevel ();
    6200          459 :   gfc_init_block (&caf_init_block);
    6201              : 
    6202          459 :   create_caf_accessor_register (&caf_init_block);
    6203              : 
    6204          459 :   gfc_traverse_ns (ns, generate_coarray_sym_init);
    6205              : 
    6206          459 :   DECL_SAVED_TREE (fndecl) = gfc_finish_block (&caf_init_block);
    6207          459 :   decl = getdecls ();
    6208              : 
    6209          459 :   poplevel (1, 1);
    6210          459 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
    6211              : 
    6212          918 :   DECL_SAVED_TREE (fndecl)
    6213          918 :     = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
    6214          918 :                        decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
    6215          459 :   dump_function (TDI_original, fndecl);
    6216              : 
    6217          459 :   cfun->function_end_locus = input_location;
    6218          459 :   set_cfun (NULL);
    6219              : 
    6220          459 :   if (decl_function_context (fndecl))
    6221          441 :     (void) cgraph_node::create (fndecl);
    6222              :   else
    6223           18 :     cgraph_node::finalize_function (fndecl, true);
    6224              : 
    6225          459 :   pop_function_context ();
    6226          459 :   current_function_decl = save_fn_decl;
    6227          459 : }
    6228              : 
    6229              : 
    6230              : static void
    6231       142360 : create_module_nml_decl (gfc_symbol *sym)
    6232              : {
    6233       142360 :   if (sym->attr.flavor == FL_NAMELIST)
    6234              :     {
    6235           45 :       tree decl = generate_namelist_decl (sym);
    6236           45 :       pushdecl (decl);
    6237           45 :       gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
    6238           45 :       DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
    6239           45 :       rest_of_decl_compilation (decl, 1, 0);
    6240           45 :       gfc_module_add_decl (cur_module, decl);
    6241              :     }
    6242       142360 : }
    6243              : 
    6244              : static void
    6245       265920 : gfc_handle_omp_declare_variant (gfc_symbol * sym)
    6246              : {
    6247       265920 :   if (sym->attr.external
    6248        86114 :       && sym->formal_ns
    6249        82284 :       && sym->formal_ns->omp_declare_variant)
    6250              :     {
    6251           26 :       gfc_namespace *ns = gfc_current_ns;
    6252           26 :       gfc_current_ns = sym->ns;
    6253           26 :       gfc_get_symbol_decl (sym);
    6254           26 :       gfc_current_ns = ns;
    6255              :     }
    6256       265920 : }
    6257              : 
    6258              : /* Generate all the required code for module variables.  */
    6259              : 
    6260              : void
    6261         9027 : gfc_generate_module_vars (gfc_namespace * ns)
    6262              : {
    6263         9027 :   module_namespace = ns;
    6264         9027 :   cur_module = gfc_find_module (ns->proc_name->name);
    6265              : 
    6266              :   /* Check if the frontend left the namespace in a reasonable state.  */
    6267         9027 :   gcc_assert (ns->proc_name && !ns->proc_name->tlink);
    6268              : 
    6269              :   /* Generate COMMON blocks.  */
    6270         9027 :   gfc_trans_common (ns);
    6271              : 
    6272         9027 :   has_coarray_vars_or_accessors = caf_accessor_head != NULL;
    6273              : 
    6274              :   /* Create decls for all the module variables.  */
    6275         9027 :   gfc_traverse_ns (ns, gfc_create_module_variable);
    6276         9027 :   gfc_traverse_ns (ns, create_module_nml_decl);
    6277              : 
    6278         9027 :   if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars_or_accessors)
    6279           18 :     generate_coarray_init (ns);
    6280              : 
    6281              :   /* For OpenMP, ensure that declare variant in INTERFACE is is processed
    6282              :      especially as some late diagnostic is only done on tree level.  */
    6283         9027 :   if (flag_openmp)
    6284         1071 :     gfc_traverse_ns (ns, gfc_handle_omp_declare_variant);
    6285              : 
    6286         9027 :   cur_module = NULL;
    6287              : 
    6288         9027 :   gfc_trans_use_stmts (ns);
    6289         9027 :   gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
    6290         9027 : }
    6291              : 
    6292              : 
    6293              : static void
    6294        84311 : gfc_generate_contained_functions (gfc_namespace * parent)
    6295              : {
    6296        84311 :   gfc_namespace *ns;
    6297              : 
    6298              :   /* We create all the prototypes before generating any code.  */
    6299       107213 :   for (ns = parent->contained; ns; ns = ns->sibling)
    6300              :     {
    6301              :       /* Skip namespaces from used modules.  */
    6302        22902 :       if (ns->parent != parent)
    6303            0 :         continue;
    6304              : 
    6305        22902 :       gfc_create_function_decl (ns, false);
    6306              :     }
    6307              : 
    6308       107213 :   for (ns = parent->contained; ns; ns = ns->sibling)
    6309              :     {
    6310              :       /* Skip namespaces from used modules.  */
    6311        22902 :       if (ns->parent != parent)
    6312            0 :         continue;
    6313              : 
    6314        22902 :       gfc_generate_function_code (ns);
    6315              :     }
    6316        84311 : }
    6317              : 
    6318              : 
    6319              : /* Drill down through expressions for the array specification bounds and
    6320              :    character length calling generate_local_decl for all those variables
    6321              :    that have not already been declared.  */
    6322              : 
    6323              : static void
    6324              : generate_local_decl (gfc_symbol *);
    6325              : 
    6326              : /* Traverse expr, marking all EXPR_VARIABLE symbols referenced.  */
    6327              : 
    6328              : static bool
    6329       113176 : expr_decls (gfc_expr *e, gfc_symbol *sym,
    6330              :             int *f ATTRIBUTE_UNUSED)
    6331              : {
    6332       113176 :   if (e->expr_type != EXPR_VARIABLE
    6333         7897 :             || sym == e->symtree->n.sym
    6334         7884 :             || e->symtree->n.sym->mark
    6335          744 :             || e->symtree->n.sym->ns != sym->ns)
    6336              :         return false;
    6337              : 
    6338          744 :   generate_local_decl (e->symtree->n.sym);
    6339          744 :   return false;
    6340              : }
    6341              : 
    6342              : static void
    6343       150804 : generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
    6344              : {
    6345            0 :   gfc_traverse_expr (e, sym, expr_decls, 0);
    6346         1058 : }
    6347              : 
    6348              : 
    6349              : /* Check for dependencies in the character length and array spec.  */
    6350              : 
    6351              : static void
    6352       193665 : generate_dependency_declarations (gfc_symbol *sym)
    6353              : {
    6354       193665 :   int i;
    6355              : 
    6356       193665 :   if (sym->ts.type == BT_CHARACTER
    6357        17290 :       && sym->ts.u.cl
    6358        17290 :       && sym->ts.u.cl->length
    6359        14196 :       && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
    6360         1058 :     generate_expr_decls (sym, sym->ts.u.cl->length);
    6361              : 
    6362       193665 :   if (sym->as && sym->as->rank)
    6363              :     {
    6364       126657 :       for (i = 0; i < sym->as->rank; i++)
    6365              :         {
    6366        74873 :           generate_expr_decls (sym, sym->as->lower[i]);
    6367        74873 :           generate_expr_decls (sym, sym->as->upper[i]);
    6368              :         }
    6369              :     }
    6370       193665 : }
    6371              : 
    6372              : 
    6373              : /* Generate decls for all local variables.  We do this to ensure correct
    6374              :    handling of expressions which only appear in the specification of
    6375              :    other functions.  */
    6376              : 
    6377              : static void
    6378      1082777 : generate_local_decl (gfc_symbol * sym)
    6379              : {
    6380      1082777 :   if (sym->attr.flavor == FL_VARIABLE)
    6381              :     {
    6382       287650 :       if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
    6383          581 :           && sym->attr.referenced && !sym->attr.use_assoc)
    6384          531 :         has_coarray_vars_or_accessors = true;
    6385              : 
    6386       287650 :       if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
    6387       193665 :         generate_dependency_declarations (sym);
    6388              : 
    6389       287650 :       if (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK))
    6390              :         {
    6391            2 :           if (sym->attr.dummy)
    6392            1 :             gfc_error ("Symbol %qs at %L has the WEAK attribute but is a "
    6393              :                        "dummy argument", sym->name, &sym->declared_at);
    6394              :           else
    6395            1 :             gfc_error ("Symbol %qs at %L has the WEAK attribute but is a "
    6396              :                        "local variable", sym->name, &sym->declared_at);
    6397              :         }
    6398              : 
    6399       287650 :       if (sym->attr.referenced)
    6400       253444 :         gfc_get_symbol_decl (sym);
    6401              : 
    6402              :       /* Warnings for unused dummy arguments.  */
    6403        34206 :       else if (sym->attr.dummy && !sym->attr.in_namelist)
    6404              :         {
    6405              :           /* INTENT(out) dummy arguments are likely meant to be set.  */
    6406         6543 :           if (warn_unused_dummy_argument && sym->attr.intent == INTENT_OUT)
    6407              :             {
    6408            9 :               if (sym->ts.type != BT_DERIVED)
    6409            6 :                 gfc_warning (OPT_Wunused_dummy_argument,
    6410              :                              "Dummy argument %qs at %L was declared "
    6411              :                              "INTENT(OUT) but was not set",  sym->name,
    6412              :                              &sym->declared_at);
    6413            3 :               else if (!gfc_has_default_initializer (sym->ts.u.derived)
    6414            3 :                        && !sym->ts.u.derived->attr.zero_comp)
    6415            1 :                 gfc_warning (OPT_Wunused_dummy_argument,
    6416              :                              "Derived-type dummy argument %qs at %L was "
    6417              :                              "declared INTENT(OUT) but was not set and "
    6418              :                              "does not have a default initializer",
    6419              :                              sym->name, &sym->declared_at);
    6420            9 :               if (sym->backend_decl != NULL_TREE)
    6421            9 :                 suppress_warning (sym->backend_decl);
    6422              :             }
    6423         6534 :           else if (warn_unused_dummy_argument)
    6424              :             {
    6425           12 :               if (!sym->attr.artificial)
    6426            4 :                 gfc_warning (OPT_Wunused_dummy_argument,
    6427              :                              "Unused dummy argument %qs at %L", sym->name,
    6428              :                              &sym->declared_at);
    6429              : 
    6430           12 :               if (sym->backend_decl != NULL_TREE)
    6431            4 :                 suppress_warning (sym->backend_decl);
    6432              :             }
    6433              :         }
    6434              : 
    6435              :       /* Warn for unused variables, but not if they're inside a common
    6436              :          block or a namelist.  */
    6437        27663 :       else if (warn_unused_variable
    6438           45 :                && !(sym->attr.in_common || sym->mark || sym->attr.in_namelist))
    6439              :         {
    6440           43 :           if (sym->attr.use_only)
    6441              :             {
    6442            1 :               gfc_warning (OPT_Wunused_variable,
    6443              :                            "Unused module variable %qs which has been "
    6444              :                            "explicitly imported at %L", sym->name,
    6445              :                            &sym->declared_at);
    6446            1 :               if (sym->backend_decl != NULL_TREE)
    6447            0 :                 suppress_warning (sym->backend_decl);
    6448              :             }
    6449           42 :           else if (!sym->attr.use_assoc)
    6450              :             {
    6451              :               /* Corner case: the symbol may be an entry point.  At this point,
    6452              :                  it may appear to be an unused variable.  Suppress warning.  */
    6453            8 :               bool enter = false;
    6454            8 :               gfc_entry_list *el;
    6455              : 
    6456           14 :               for (el = sym->ns->entries; el; el=el->next)
    6457            6 :                 if (strcmp(sym->name, el->sym->name) == 0)
    6458            2 :                   enter = true;
    6459              : 
    6460            8 :               if (!enter)
    6461            6 :                 gfc_warning (OPT_Wunused_variable,
    6462              :                              "Unused variable %qs declared at %L",
    6463              :                              sym->name, &sym->declared_at);
    6464            8 :               if (sym->backend_decl != NULL_TREE)
    6465            0 :                 suppress_warning (sym->backend_decl);
    6466              :             }
    6467              :         }
    6468              : 
    6469              :       /* For variable length CHARACTER parameters, the PARM_DECL already
    6470              :          references the length variable, so force gfc_get_symbol_decl
    6471              :          even when not referenced.  If optimize > 0, it will be optimized
    6472              :          away anyway.  But do this only after emitting -Wunused-parameter
    6473              :          warning if requested.  */
    6474       287650 :       if (sym->attr.dummy && !sym->attr.referenced
    6475         6546 :             && sym->ts.type == BT_CHARACTER
    6476          815 :             && sym->ts.u.cl->backend_decl != NULL
    6477          810 :             && VAR_P (sym->ts.u.cl->backend_decl))
    6478              :         {
    6479            6 :           sym->attr.referenced = 1;
    6480            6 :           gfc_get_symbol_decl (sym);
    6481              :         }
    6482              : 
    6483              :       /* INTENT(out) dummy arguments and result variables with allocatable
    6484              :          components are reset by default and need to be set referenced to
    6485              :          generate the code for nullification and automatic lengths.  */
    6486       287650 :       if (!sym->attr.referenced
    6487        34200 :             && sym->ts.type == BT_DERIVED
    6488        20349 :             && sym->ts.u.derived->attr.alloc_comp
    6489         1606 :             && !sym->attr.pointer
    6490         1605 :             && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT)
    6491         1569 :                   ||
    6492         1569 :                 (sym->attr.result && sym != sym->result)))
    6493              :         {
    6494           36 :           sym->attr.referenced = 1;
    6495           36 :           gfc_get_symbol_decl (sym);
    6496              :         }
    6497              : 
    6498              :       /* Check for dependencies in the array specification and string
    6499              :         length, adding the necessary declarations to the function.  We
    6500              :         mark the symbol now, as well as in traverse_ns, to prevent
    6501              :         getting stuck in a circular dependency.  */
    6502       287650 :       sym->mark = 1;
    6503              :     }
    6504       795127 :   else if (sym->attr.flavor == FL_PARAMETER)
    6505              :     {
    6506       206517 :       if (warn_unused_parameter
    6507          488 :            && !sym->attr.referenced)
    6508              :         {
    6509          431 :            if (!sym->attr.use_assoc)
    6510            4 :              gfc_warning (OPT_Wunused_parameter,
    6511              :                           "Unused parameter %qs declared at %L", sym->name,
    6512              :                           &sym->declared_at);
    6513          427 :            else if (sym->attr.use_only)
    6514            1 :              gfc_warning (OPT_Wunused_parameter,
    6515              :                           "Unused parameter %qs which has been explicitly "
    6516              :                           "imported at %L", sym->name, &sym->declared_at);
    6517              :         }
    6518              : 
    6519       206517 :       if (sym->ns && sym->ns->construct_entities)
    6520              :         {
    6521              :           /* Construction of the intrinsic modules within a BLOCK
    6522              :              construct, where ONLY and RENAMED entities are included,
    6523              :              seems to be bogus.  This is a workaround that can be removed
    6524              :              if someone ever takes on the task to creating full-fledge
    6525              :              modules.  See PR 69455.  */
    6526           78 :           if (sym->attr.referenced
    6527           78 :               && sym->from_intmod != INTMOD_ISO_C_BINDING
    6528           54 :               && sym->from_intmod != INTMOD_ISO_FORTRAN_ENV)
    6529           26 :             gfc_get_symbol_decl (sym);
    6530           78 :           sym->mark = 1;
    6531              :         }
    6532              :     }
    6533       588610 :   else if (sym->attr.flavor == FL_PROCEDURE)
    6534              :     {
    6535              :       /* TODO: move to the appropriate place in resolve.cc.  */
    6536       489298 :       if (warn_return_type > 0
    6537         4704 :           && sym->attr.function
    6538         3430 :           && sym->result
    6539         3222 :           && sym != sym->result
    6540          444 :           && !sym->result->attr.referenced
    6541           36 :           && !sym->attr.use_assoc
    6542           23 :           && sym->attr.if_source != IFSRC_IFBODY)
    6543              :         {
    6544           23 :           gfc_warning (OPT_Wreturn_type,
    6545              :                        "Return value %qs of function %qs declared at "
    6546              :                        "%L not set", sym->result->name, sym->name,
    6547              :                         &sym->result->declared_at);
    6548              : 
    6549              :           /* Prevents "Unused variable" warning for RESULT variables.  */
    6550           23 :           sym->result->mark = 1;
    6551              :         }
    6552              :     }
    6553              : 
    6554      1082777 :   if (sym->attr.dummy == 1)
    6555              :     {
    6556              :       /* The tree type for scalar character dummy arguments of BIND(C)
    6557              :          procedures, if they are passed by value, should be unsigned char.
    6558              :          The value attribute implies the dummy is a scalar.  */
    6559       100740 :       if (sym->attr.value == 1 && sym->backend_decl != NULL
    6560         8351 :           && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
    6561          254 :           && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
    6562              :         {
    6563              :           /* We used to modify the tree here. Now it is done earlier in
    6564              :              the front-end, so we only check it here to avoid regressions.  */
    6565          242 :           gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
    6566          242 :           gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
    6567          242 :           gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
    6568          242 :           gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
    6569              :         }
    6570              : 
    6571              :       /* Unused procedure passed as dummy argument.  */
    6572       100740 :       if (sym->attr.flavor == FL_PROCEDURE)
    6573              :         {
    6574          901 :           if (!sym->attr.referenced && !sym->attr.artificial)
    6575              :             {
    6576           58 :               if (warn_unused_dummy_argument)
    6577            2 :                 gfc_warning (OPT_Wunused_dummy_argument,
    6578              :                              "Unused dummy argument %qs at %L", sym->name,
    6579              :                              &sym->declared_at);
    6580              :             }
    6581              : 
    6582              :           /* Silence bogus "unused parameter" warnings from the
    6583              :              middle end.  */
    6584          901 :           if (sym->backend_decl != NULL_TREE)
    6585          900 :                 suppress_warning (sym->backend_decl);
    6586              :         }
    6587              :     }
    6588              : 
    6589              :   /* Make sure we convert the types of the derived types from iso_c_binding
    6590              :      into (void *).  */
    6591      1082777 :   if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
    6592        79602 :       && sym->ts.type == BT_DERIVED)
    6593         3367 :     sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
    6594      1082777 : }
    6595              : 
    6596              : 
    6597              : static void
    6598      1082784 : generate_local_nml_decl (gfc_symbol * sym)
    6599              : {
    6600      1082784 :   if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
    6601              :     {
    6602          698 :       tree decl = generate_namelist_decl (sym);
    6603          698 :       pushdecl (decl);
    6604              :     }
    6605      1082784 : }
    6606              : 
    6607              : 
    6608              : static void
    6609        98202 : generate_local_vars (gfc_namespace * ns)
    6610              : {
    6611        98202 :   gfc_traverse_ns (ns, generate_local_decl);
    6612        98202 :   gfc_traverse_ns (ns, generate_local_nml_decl);
    6613        98202 : }
    6614              : 
    6615              : 
    6616              : /* Generate a switch statement to jump to the correct entry point.  Also
    6617              :    creates the label decls for the entry points.  */
    6618              : 
    6619              : static tree
    6620          634 : gfc_trans_entry_master_switch (gfc_entry_list * el)
    6621              : {
    6622          634 :   stmtblock_t block;
    6623          634 :   tree label;
    6624          634 :   tree tmp;
    6625          634 :   tree val;
    6626              : 
    6627          634 :   gfc_init_block (&block);
    6628         2613 :   for (; el; el = el->next)
    6629              :     {
    6630              :       /* Add the case label.  */
    6631         1345 :       label = gfc_build_label_decl (NULL_TREE);
    6632         1345 :       val = build_int_cst (gfc_array_index_type, el->id);
    6633         1345 :       tmp = build_case_label (val, NULL_TREE, label);
    6634         1345 :       gfc_add_expr_to_block (&block, tmp);
    6635              : 
    6636              :       /* And jump to the actual entry point.  */
    6637         1345 :       label = gfc_build_label_decl (NULL_TREE);
    6638         1345 :       tmp = build1_v (GOTO_EXPR, label);
    6639         1345 :       gfc_add_expr_to_block (&block, tmp);
    6640              : 
    6641              :       /* Save the label decl.  */
    6642         1345 :       el->label = label;
    6643              :     }
    6644          634 :   tmp = gfc_finish_block (&block);
    6645              :   /* The first argument selects the entry point.  */
    6646          634 :   val = DECL_ARGUMENTS (current_function_decl);
    6647          634 :   tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, val, tmp);
    6648          634 :   return tmp;
    6649              : }
    6650              : 
    6651              : 
    6652              : /* Add code to string lengths of actual arguments passed to a function against
    6653              :    the expected lengths of the dummy arguments.  */
    6654              : 
    6655              : static void
    6656         2809 : add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
    6657              : {
    6658         2809 :   gfc_formal_arglist *formal;
    6659              : 
    6660         5513 :   for (formal = gfc_sym_get_dummy_args (sym); formal; formal = formal->next)
    6661         2704 :     if (formal->sym && formal->sym->ts.type == BT_CHARACTER
    6662          604 :         && !formal->sym->ts.deferred)
    6663              :       {
    6664          554 :         enum tree_code comparison;
    6665          554 :         tree cond;
    6666          554 :         tree argname;
    6667          554 :         gfc_symbol *fsym;
    6668          554 :         gfc_charlen *cl;
    6669          554 :         const char *message;
    6670              : 
    6671          554 :         fsym = formal->sym;
    6672          554 :         cl = fsym->ts.u.cl;
    6673              : 
    6674          554 :         gcc_assert (cl);
    6675          554 :         gcc_assert (cl->passed_length != NULL_TREE);
    6676          554 :         gcc_assert (cl->backend_decl != NULL_TREE);
    6677              : 
    6678              :         /* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the
    6679              :            string lengths must match exactly.  Otherwise, it is only required
    6680              :            that the actual string length is *at least* the expected one.
    6681              :            Sequence association allows for a mismatch of the string length
    6682              :            if the actual argument is (part of) an array, but only if the
    6683              :            dummy argument is an array. (See "Sequence association" in
    6684              :            Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.)  */
    6685          554 :         if (fsym->attr.pointer || fsym->attr.allocatable
    6686          446 :             || (fsym->as && (fsym->as->type == AS_ASSUMED_SHAPE
    6687           33 :                              || fsym->as->type == AS_ASSUMED_RANK)))
    6688              :           {
    6689          196 :             comparison = NE_EXPR;
    6690          196 :             message = _("Actual string length does not match the declared one"
    6691              :                         " for dummy argument '%s' (%ld/%ld)");
    6692              :           }
    6693          358 :         else if ((fsym->as && fsym->as->rank != 0) || fsym->attr.artificial)
    6694           33 :           continue;
    6695              :         else
    6696              :           {
    6697          325 :             comparison = LT_EXPR;
    6698          325 :             message = _("Actual string length is shorter than the declared one"
    6699              :                         " for dummy argument '%s' (%ld/%ld)");
    6700              :           }
    6701              : 
    6702              :         /* Build the condition.  For optional arguments, an actual length
    6703              :            of 0 is also acceptable if the associated string is NULL, which
    6704              :            means the argument was not passed.  */
    6705          521 :         cond = fold_build2_loc (input_location, comparison, logical_type_node,
    6706              :                                 cl->passed_length, cl->backend_decl);
    6707          521 :         if (fsym->attr.optional)
    6708              :           {
    6709           45 :             tree not_absent;
    6710           45 :             tree not_0length;
    6711           45 :             tree absent_failed;
    6712              : 
    6713           45 :             not_0length = fold_build2_loc (input_location, NE_EXPR,
    6714              :                                            logical_type_node,
    6715              :                                            cl->passed_length,
    6716              :                                            build_zero_cst
    6717           45 :                                            (TREE_TYPE (cl->passed_length)));
    6718              :             /* The symbol needs to be referenced for gfc_get_symbol_decl.  */
    6719           45 :             fsym->attr.referenced = 1;
    6720           45 :             not_absent = gfc_conv_expr_present (fsym);
    6721              : 
    6722           45 :             absent_failed = fold_build2_loc (input_location, TRUTH_OR_EXPR,
    6723              :                                              logical_type_node, not_0length,
    6724              :                                              not_absent);
    6725              : 
    6726           45 :             cond = fold_build2_loc (input_location, TRUTH_AND_EXPR,
    6727              :                                     logical_type_node, cond, absent_failed);
    6728              :           }
    6729              : 
    6730              :         /* Build the runtime check.  */
    6731          521 :         argname = gfc_build_cstring_const (fsym->name);
    6732          521 :         argname = gfc_build_addr_expr (pchar_type_node, argname);
    6733          521 :         gfc_trans_runtime_check (true, false, cond, block, &fsym->declared_at,
    6734              :                                  message, argname,
    6735              :                                  fold_convert (long_integer_type_node,
    6736              :                                                cl->passed_length),
    6737              :                                  fold_convert (long_integer_type_node,
    6738              :                                                cl->backend_decl));
    6739              :       }
    6740         2809 : }
    6741              : 
    6742              : 
    6743              : static void
    6744        26085 : create_main_function (tree fndecl)
    6745              : {
    6746        26085 :   tree old_context;
    6747        26085 :   tree ftn_main;
    6748        26085 :   tree tmp, decl, result_decl, argc, argv, typelist, arglist;
    6749        26085 :   stmtblock_t body;
    6750              : 
    6751        26085 :   old_context = current_function_decl;
    6752              : 
    6753        26085 :   if (old_context)
    6754              :     {
    6755            0 :       push_function_context ();
    6756            0 :       saved_parent_function_decls = saved_function_decls;
    6757            0 :       saved_function_decls = NULL_TREE;
    6758              :     }
    6759              : 
    6760              :   /* main() function must be declared with global scope.  */
    6761        26085 :   gcc_assert (current_function_decl == NULL_TREE);
    6762              : 
    6763              :   /* Declare the function.  */
    6764        26085 :   tmp =  build_function_type_list (integer_type_node, integer_type_node,
    6765              :                                    build_pointer_type (pchar_type_node),
    6766              :                                    NULL_TREE);
    6767        26085 :   main_identifier_node = get_identifier ("main");
    6768        26085 :   ftn_main = build_decl (input_location, FUNCTION_DECL,
    6769              :                          main_identifier_node, tmp);
    6770        26085 :   DECL_EXTERNAL (ftn_main) = 0;
    6771        26085 :   TREE_PUBLIC (ftn_main) = 1;
    6772        26085 :   TREE_STATIC (ftn_main) = 1;
    6773        26085 :   DECL_ATTRIBUTES (ftn_main)
    6774        26085 :       = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
    6775              : 
    6776              :   /* Setup the result declaration (for "return 0").  */
    6777        26085 :   result_decl = build_decl (input_location,
    6778              :                             RESULT_DECL, NULL_TREE, integer_type_node);
    6779        26085 :   DECL_ARTIFICIAL (result_decl) = 1;
    6780        26085 :   DECL_IGNORED_P (result_decl) = 1;
    6781        26085 :   DECL_CONTEXT (result_decl) = ftn_main;
    6782        26085 :   DECL_RESULT (ftn_main) = result_decl;
    6783              : 
    6784        26085 :   pushdecl (ftn_main);
    6785              : 
    6786              :   /* Get the arguments.  */
    6787              : 
    6788        26085 :   arglist = NULL_TREE;
    6789        26085 :   typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
    6790              : 
    6791        26085 :   tmp = TREE_VALUE (typelist);
    6792        26085 :   argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
    6793        26085 :   DECL_CONTEXT (argc) = ftn_main;
    6794        26085 :   DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
    6795        26085 :   TREE_READONLY (argc) = 1;
    6796        26085 :   gfc_finish_decl (argc);
    6797        26085 :   arglist = chainon (arglist, argc);
    6798              : 
    6799        26085 :   typelist = TREE_CHAIN (typelist);
    6800        26085 :   tmp = TREE_VALUE (typelist);
    6801        26085 :   argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
    6802        26085 :   DECL_CONTEXT (argv) = ftn_main;
    6803        26085 :   DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
    6804        26085 :   TREE_READONLY (argv) = 1;
    6805        26085 :   DECL_BY_REFERENCE (argv) = 1;
    6806        26085 :   gfc_finish_decl (argv);
    6807        26085 :   arglist = chainon (arglist, argv);
    6808              : 
    6809        26085 :   DECL_ARGUMENTS (ftn_main) = arglist;
    6810        26085 :   current_function_decl = ftn_main;
    6811        26085 :   announce_function (ftn_main);
    6812              : 
    6813        26085 :   rest_of_decl_compilation (ftn_main, 1, 0);
    6814        26085 :   make_decl_rtl (ftn_main);
    6815        26085 :   allocate_struct_function (ftn_main, false);
    6816        26085 :   pushlevel ();
    6817              : 
    6818        26085 :   gfc_init_block (&body);
    6819              : 
    6820              :   /* Call some libgfortran initialization routines, call then MAIN__().  */
    6821              : 
    6822              :   /* Call _gfortran_caf_init (*argc, ***argv).  */
    6823        26085 :   if (flag_coarray == GFC_FCOARRAY_LIB)
    6824              :     {
    6825          396 :       tree pint_type, pppchar_type;
    6826          396 :       pint_type = build_pointer_type (integer_type_node);
    6827          396 :       pppchar_type
    6828          396 :         = build_pointer_type (build_pointer_type (pchar_type_node));
    6829              : 
    6830          396 :       tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 2,
    6831              :                 gfc_build_addr_expr (pint_type, argc),
    6832              :                 gfc_build_addr_expr (pppchar_type, argv));
    6833          396 :       gfc_add_expr_to_block (&body, tmp);
    6834              :     }
    6835              : 
    6836              :   /* Call _gfortran_set_args (argc, argv).  */
    6837        26085 :   TREE_USED (argc) = 1;
    6838        26085 :   TREE_USED (argv) = 1;
    6839        26085 :   tmp = build_call_expr_loc (input_location,
    6840              :                          gfor_fndecl_set_args, 2, argc, argv);
    6841        26085 :   gfc_add_expr_to_block (&body, tmp);
    6842              : 
    6843              :   /* Add a call to set_options to set up the runtime library Fortran
    6844              :      language standard parameters.  */
    6845        26085 :   {
    6846        26085 :     tree array_type, array, var;
    6847        26085 :     vec<constructor_elt, va_gc> *v = NULL;
    6848        26085 :     static const int noptions = 7;
    6849              : 
    6850              :     /* Passing a new option to the library requires three modifications:
    6851              :           + add it to the tree_cons list below
    6852              :           + change the noptions variable above
    6853              :           + modify the library (runtime/compile_options.c)!  */
    6854              : 
    6855        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6856              :                             build_int_cst (integer_type_node,
    6857              :                                            gfc_option.warn_std));
    6858        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6859              :                             build_int_cst (integer_type_node,
    6860              :                                            gfc_option.allow_std));
    6861        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6862              :                             build_int_cst (integer_type_node, pedantic));
    6863        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6864              :                             build_int_cst (integer_type_node, flag_backtrace));
    6865        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6866              :                             build_int_cst (integer_type_node, flag_sign_zero));
    6867        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6868              :                             build_int_cst (integer_type_node,
    6869              :                                            (gfc_option.rtcheck
    6870              :                                             & GFC_RTCHECK_BOUNDS)));
    6871        26085 :     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
    6872              :                             build_int_cst (integer_type_node,
    6873              :                                            gfc_option.fpe_summary));
    6874              : 
    6875        26085 :     array_type = build_array_type_nelts (integer_type_node, noptions);
    6876        26085 :     array = build_constructor (array_type, v);
    6877        26085 :     TREE_CONSTANT (array) = 1;
    6878        26085 :     TREE_STATIC (array) = 1;
    6879              : 
    6880              :     /* Create a static variable to hold the jump table.  */
    6881        26085 :     var = build_decl (input_location, VAR_DECL,
    6882              :                       create_tmp_var_name ("options"), array_type);
    6883        26085 :     DECL_ARTIFICIAL (var) = 1;
    6884        26085 :     DECL_IGNORED_P (var) = 1;
    6885        26085 :     TREE_CONSTANT (var) = 1;
    6886        26085 :     TREE_STATIC (var) = 1;
    6887        26085 :     TREE_READONLY (var) = 1;
    6888        26085 :     DECL_INITIAL (var) = array;
    6889        26085 :     pushdecl (var);
    6890        26085 :     var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var);
    6891              : 
    6892        26085 :     tmp = build_call_expr_loc (input_location,
    6893              :                            gfor_fndecl_set_options, 2,
    6894              :                            build_int_cst (integer_type_node, noptions), var);
    6895        26085 :     gfc_add_expr_to_block (&body, tmp);
    6896              :   }
    6897              : 
    6898              :   /* If -ffpe-trap option was provided, add a call to set_fpe so that
    6899              :      the library will raise a FPE when needed.  */
    6900        26085 :   if (gfc_option.fpe != 0)
    6901              :     {
    6902            6 :       tmp = build_call_expr_loc (input_location,
    6903              :                              gfor_fndecl_set_fpe, 1,
    6904              :                              build_int_cst (integer_type_node,
    6905            6 :                                             gfc_option.fpe));
    6906            6 :       gfc_add_expr_to_block (&body, tmp);
    6907              :     }
    6908              : 
    6909              :   /* If this is the main program and an -fconvert option was provided,
    6910              :      add a call to set_convert.  */
    6911              : 
    6912        26085 :   if (flag_convert != GFC_FLAG_CONVERT_NATIVE)
    6913              :     {
    6914           12 :       tmp = build_call_expr_loc (input_location,
    6915              :                              gfor_fndecl_set_convert, 1,
    6916           12 :                              build_int_cst (integer_type_node, flag_convert));
    6917           12 :       gfc_add_expr_to_block (&body, tmp);
    6918              :     }
    6919              : 
    6920              :   /* If this is the main program and an -frecord-marker option was provided,
    6921              :      add a call to set_record_marker.  */
    6922              : 
    6923        26085 :   if (flag_record_marker != 0)
    6924              :     {
    6925           18 :       tmp = build_call_expr_loc (input_location,
    6926              :                              gfor_fndecl_set_record_marker, 1,
    6927              :                              build_int_cst (integer_type_node,
    6928           18 :                                             flag_record_marker));
    6929           18 :       gfc_add_expr_to_block (&body, tmp);
    6930              :     }
    6931              : 
    6932        26085 :   if (flag_max_subrecord_length != 0)
    6933              :     {
    6934            6 :       tmp = build_call_expr_loc (input_location,
    6935              :                              gfor_fndecl_set_max_subrecord_length, 1,
    6936              :                              build_int_cst (integer_type_node,
    6937            6 :                                             flag_max_subrecord_length));
    6938            6 :       gfc_add_expr_to_block (&body, tmp);
    6939              :     }
    6940              : 
    6941              :   /* Call MAIN__().  */
    6942        26085 :   tmp = build_call_expr_loc (input_location,
    6943              :                          fndecl, 0);
    6944        26085 :   gfc_add_expr_to_block (&body, tmp);
    6945              : 
    6946              :   /* Mark MAIN__ as used.  */
    6947        26085 :   TREE_USED (fndecl) = 1;
    6948              : 
    6949              :   /* Coarray: Call _gfortran_caf_finalize(void).  */
    6950        26085 :   if (flag_coarray == GFC_FCOARRAY_LIB)
    6951              :     {
    6952          396 :       tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_finalize, 0);
    6953          396 :       gfc_add_expr_to_block (&body, tmp);
    6954              :     }
    6955              : 
    6956              :   /* "return 0".  */
    6957        26085 :   tmp = fold_build2_loc (input_location, MODIFY_EXPR, integer_type_node,
    6958        26085 :                          DECL_RESULT (ftn_main),
    6959              :                          integer_zero_node);
    6960        26085 :   tmp = build1_v (RETURN_EXPR, tmp);
    6961        26085 :   gfc_add_expr_to_block (&body, tmp);
    6962              : 
    6963              : 
    6964        26085 :   DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body);
    6965        26085 :   decl = getdecls ();
    6966              : 
    6967              :   /* Finish off this function and send it for code generation.  */
    6968        26085 :   poplevel (1, 1);
    6969        26085 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main;
    6970              : 
    6971        52170 :   DECL_SAVED_TREE (ftn_main)
    6972        52170 :     = fold_build3_loc (DECL_SOURCE_LOCATION (ftn_main), BIND_EXPR,
    6973        26085 :                        void_type_node, decl, DECL_SAVED_TREE (ftn_main),
    6974        26085 :                        DECL_INITIAL (ftn_main));
    6975              : 
    6976              :   /* Output the GENERIC tree.  */
    6977        26085 :   dump_function (TDI_original, ftn_main);
    6978              : 
    6979        26085 :   cgraph_node::finalize_function (ftn_main, true);
    6980              : 
    6981        26085 :   if (old_context)
    6982              :     {
    6983            0 :       pop_function_context ();
    6984            0 :       saved_function_decls = saved_parent_function_decls;
    6985              :     }
    6986        26085 :   current_function_decl = old_context;
    6987        26085 : }
    6988              : 
    6989              : 
    6990              : /* Generate an appropriate return-statement for a procedure.  */
    6991              : 
    6992              : tree
    6993        14950 : gfc_generate_return (void)
    6994              : {
    6995        14950 :   gfc_symbol* sym;
    6996        14950 :   tree result;
    6997        14950 :   tree fndecl;
    6998              : 
    6999        14950 :   sym = current_procedure_symbol;
    7000        14950 :   fndecl = sym->backend_decl;
    7001              : 
    7002        14950 :   if (TREE_TYPE (DECL_RESULT (fndecl)) == void_type_node)
    7003              :     result = NULL_TREE;
    7004              :   else
    7005              :     {
    7006        12698 :       result = get_proc_result (sym);
    7007              : 
    7008              :       /* Set the return value to the dummy result variable.  The
    7009              :          types may be different for scalar default REAL functions
    7010              :          with -ff2c, therefore we have to convert.  */
    7011        12698 :       if (result != NULL_TREE)
    7012              :         {
    7013        12687 :           result = convert (TREE_TYPE (DECL_RESULT (fndecl)), result);
    7014        25374 :           result = fold_build2_loc (input_location, MODIFY_EXPR,
    7015        12687 :                                     TREE_TYPE (result), DECL_RESULT (fndecl),
    7016              :                                     result);
    7017              :         }
    7018              :       else
    7019              :         {
    7020              :           /* If the function does not have a result variable, result is
    7021              :              NULL_TREE, and a 'return' is generated without a variable.
    7022              :              The following generates a 'return __result_XXX' where XXX is
    7023              :              the function name.  */
    7024           11 :           if (sym == sym->result && sym->attr.function && !flag_f2c)
    7025              :             {
    7026            8 :               result = gfc_get_fake_result_decl (sym, 0);
    7027           16 :               result = fold_build2_loc (input_location, MODIFY_EXPR,
    7028            8 :                                         TREE_TYPE (result),
    7029            8 :                                         DECL_RESULT (fndecl), result);
    7030              :             }
    7031              :         }
    7032              :     }
    7033              : 
    7034        14950 :   return build1_v (RETURN_EXPR, result);
    7035              : }
    7036              : 
    7037              : 
    7038              : static void
    7039      1052304 : is_from_ieee_module (gfc_symbol *sym)
    7040              : {
    7041      1052304 :   if (sym->from_intmod == INTMOD_IEEE_FEATURES
    7042              :       || sym->from_intmod == INTMOD_IEEE_EXCEPTIONS
    7043      1052304 :       || sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
    7044       121760 :     seen_ieee_symbol = 1;
    7045      1052304 : }
    7046              : 
    7047              : 
    7048              : static int
    7049        84311 : is_ieee_module_used (gfc_namespace *ns)
    7050              : {
    7051        84311 :   seen_ieee_symbol = 0;
    7052            0 :   gfc_traverse_ns (ns, is_from_ieee_module);
    7053        84311 :   return seen_ieee_symbol;
    7054              : }
    7055              : 
    7056              : 
    7057              : static gfc_omp_clauses *module_oacc_clauses;
    7058              : 
    7059              : 
    7060              : static void
    7061          146 : add_clause (gfc_symbol *sym, gfc_omp_map_op map_op)
    7062              : {
    7063          146 :   gfc_omp_namelist *n;
    7064              : 
    7065          146 :   n = gfc_get_omp_namelist ();
    7066          146 :   n->sym = sym;
    7067          146 :   n->where = sym->declared_at;
    7068          146 :   n->u.map.op = map_op;
    7069              : 
    7070          146 :   if (!module_oacc_clauses)
    7071          124 :     module_oacc_clauses = gfc_get_omp_clauses ();
    7072              : 
    7073          146 :   if (module_oacc_clauses->lists[OMP_LIST_MAP])
    7074           22 :     n->next = module_oacc_clauses->lists[OMP_LIST_MAP];
    7075              : 
    7076          146 :   module_oacc_clauses->lists[OMP_LIST_MAP] = n;
    7077          146 : }
    7078              : 
    7079              : 
    7080              : static void
    7081      1082784 : find_module_oacc_declare_clauses (gfc_symbol *sym)
    7082              : {
    7083      1082784 :   if (sym->attr.use_assoc)
    7084              :     {
    7085       508312 :       gfc_omp_map_op map_op;
    7086              : 
    7087       508312 :       if (sym->attr.oacc_declare_create)
    7088       508312 :         map_op = OMP_MAP_FORCE_ALLOC;
    7089              : 
    7090       508312 :       if (sym->attr.oacc_declare_copyin)
    7091            2 :         map_op = OMP_MAP_FORCE_TO;
    7092              : 
    7093       508312 :       if (sym->attr.oacc_declare_deviceptr)
    7094            0 :         map_op = OMP_MAP_FORCE_DEVICEPTR;
    7095              : 
    7096       508312 :       if (sym->attr.oacc_declare_device_resident)
    7097           34 :         map_op = OMP_MAP_DEVICE_RESIDENT;
    7098              : 
    7099       508312 :       if (sym->attr.oacc_declare_create
    7100       508202 :           || sym->attr.oacc_declare_copyin
    7101       508200 :           || sym->attr.oacc_declare_deviceptr
    7102       508200 :           || sym->attr.oacc_declare_device_resident)
    7103              :         {
    7104          146 :           sym->attr.referenced = 1;
    7105          146 :           add_clause (sym, map_op);
    7106              :         }
    7107              :     }
    7108      1082784 : }
    7109              : 
    7110              : 
    7111              : void
    7112        98202 : finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
    7113              : {
    7114        98202 :   gfc_code *code;
    7115        98202 :   gfc_oacc_declare *oc;
    7116        98202 :   locus where;
    7117        98202 :   gfc_omp_clauses *omp_clauses = NULL;
    7118        98202 :   gfc_omp_namelist *n, *p;
    7119        98202 :   module_oacc_clauses = NULL;
    7120              : 
    7121        98202 :   gfc_locus_from_location (&where, input_location);
    7122        98202 :   gfc_traverse_ns (ns, find_module_oacc_declare_clauses);
    7123              : 
    7124        98202 :   if (module_oacc_clauses && sym->attr.flavor == FL_PROGRAM)
    7125              :     {
    7126           45 :       gfc_oacc_declare *new_oc;
    7127              : 
    7128           45 :       new_oc = gfc_get_oacc_declare ();
    7129           45 :       new_oc->next = ns->oacc_declare;
    7130           45 :       new_oc->clauses = module_oacc_clauses;
    7131              : 
    7132           45 :       ns->oacc_declare = new_oc;
    7133              :     }
    7134              : 
    7135        98202 :   if (!ns->oacc_declare)
    7136              :     return;
    7137              : 
    7138          190 :   for (oc = ns->oacc_declare; oc; oc = oc->next)
    7139              :     {
    7140          101 :       if (oc->module_var)
    7141            0 :         continue;
    7142              : 
    7143          101 :       if (block)
    7144            2 :         gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
    7145              :                    "in BLOCK construct", &oc->loc);
    7146              : 
    7147              : 
    7148          101 :       if (oc->clauses && oc->clauses->lists[OMP_LIST_MAP])
    7149              :         {
    7150           88 :           if (omp_clauses == NULL)
    7151              :             {
    7152           76 :               omp_clauses = oc->clauses;
    7153           76 :               continue;
    7154              :             }
    7155              : 
    7156           48 :           for (n = oc->clauses->lists[OMP_LIST_MAP]; n; p = n, n = n->next)
    7157              :             ;
    7158              : 
    7159           12 :           gcc_assert (p->next == NULL);
    7160              : 
    7161           12 :           p->next = omp_clauses->lists[OMP_LIST_MAP];
    7162           12 :           omp_clauses = oc->clauses;
    7163              :         }
    7164              :     }
    7165              : 
    7166           89 :   if (!omp_clauses)
    7167              :     return;
    7168              : 
    7169          212 :   for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
    7170              :     {
    7171          136 :       switch (n->u.map.op)
    7172              :         {
    7173           27 :           case OMP_MAP_DEVICE_RESIDENT:
    7174           27 :             n->u.map.op = OMP_MAP_FORCE_ALLOC;
    7175           27 :             break;
    7176              : 
    7177              :           default:
    7178              :             break;
    7179              :         }
    7180              :     }
    7181              : 
    7182           76 :   code = XCNEW (gfc_code);
    7183           76 :   code->op = EXEC_OACC_DECLARE;
    7184           76 :   code->loc = where;
    7185              : 
    7186           76 :   code->ext.oacc_declare = gfc_get_oacc_declare ();
    7187           76 :   code->ext.oacc_declare->clauses = omp_clauses;
    7188              : 
    7189           76 :   code->block = XCNEW (gfc_code);
    7190           76 :   code->block->op = EXEC_OACC_DECLARE;
    7191           76 :   code->block->loc = where;
    7192              : 
    7193           76 :   if (ns->code)
    7194           73 :     code->block->next = ns->code;
    7195              : 
    7196           76 :   ns->code = code;
    7197              : 
    7198           76 :   return;
    7199              : }
    7200              : 
    7201              : static void
    7202         1819 : gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t *finally,
    7203              :                      tree cfi_desc, tree gfc_desc, gfc_symbol *sym)
    7204              : {
    7205         1819 :   stmtblock_t block;
    7206         1819 :   gfc_init_block (&block);
    7207         1819 :   tree cfi = build_fold_indirect_ref_loc (input_location, cfi_desc);
    7208         1819 :   tree idx, etype, tmp, tmp2, size_var = NULL_TREE, rank = NULL_TREE;
    7209         1819 :   bool do_copy_inout = false;
    7210              : 
    7211              :   /* When allocatable + intent out, free the cfi descriptor.  */
    7212         1819 :   if (sym->attr.allocatable && sym->attr.intent == INTENT_OUT)
    7213              :     {
    7214           54 :       tmp = gfc_get_cfi_desc_base_addr (cfi);
    7215           54 :       tree call = builtin_decl_explicit (BUILT_IN_FREE);
    7216           54 :       call = build_call_expr_loc (input_location, call, 1, tmp);
    7217           54 :       gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
    7218           54 :       gfc_add_modify (&block, tmp,
    7219           54 :                       fold_convert (TREE_TYPE (tmp), null_pointer_node));
    7220              :     }
    7221              : 
    7222              :   /* -fcheck=bound: Do version, rank, attribute, type and is-NULL checks.  */
    7223         1819 :   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
    7224              :     {
    7225          654 :       char *msg;
    7226          654 :       tree tmp3;
    7227          654 :       msg = xasprintf ("Unexpected version %%d (expected %d) in CFI descriptor "
    7228              :                        "passed to dummy argument %s", CFI_VERSION, sym->name);
    7229          654 :       tmp2 = gfc_get_cfi_desc_version (cfi);
    7230          654 :       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp2,
    7231          654 :                              build_int_cst (TREE_TYPE (tmp2), CFI_VERSION));
    7232          654 :       gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
    7233              :                                msg, tmp2);
    7234          654 :       free (msg);
    7235              : 
    7236              :       /* Rank check; however, for character(len=*), assumed/explicit-size arrays
    7237              :          are permitted to differ in rank according to the Fortran rules.  */
    7238          654 :       if (sym->as && sym->as->type != AS_ASSUMED_SIZE
    7239          546 :           && sym->as->type != AS_EXPLICIT)
    7240              :         {
    7241          438 :           if (sym->as->rank != -1)
    7242          222 :             msg = xasprintf ("Invalid rank %%d (expected %d) in CFI descriptor "
    7243              :                              "passed to dummy argument %s", sym->as->rank,
    7244              :                              sym->name);
    7245              :           else
    7246          216 :             msg = xasprintf ("Invalid rank %%d (expected 0..%d) in CFI "
    7247              :                              "descriptor passed to dummy argument %s",
    7248              :                              CFI_MAX_RANK, sym->name);
    7249              : 
    7250          438 :           tmp3 = tmp2 = tmp = gfc_get_cfi_desc_rank (cfi);
    7251          438 :           if (sym->as->rank != -1)
    7252          222 :             tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7253              :                                    tmp, build_int_cst (signed_char_type_node,
    7254          222 :                                                        sym->as->rank));
    7255              :           else
    7256              :             {
    7257          216 :               tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
    7258          216 :                                      tmp, build_zero_cst (TREE_TYPE (tmp)));
    7259          216 :               tmp2 = fold_build2_loc (input_location, GT_EXPR,
    7260              :                                       boolean_type_node, tmp2,
    7261          216 :                                       build_int_cst (TREE_TYPE (tmp2),
    7262              :                                                      CFI_MAX_RANK));
    7263          216 :               tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
    7264              :                                      boolean_type_node, tmp, tmp2);
    7265              :             }
    7266          438 :           gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
    7267              :                                    msg, tmp3);
    7268          438 :           free (msg);
    7269              :         }
    7270              : 
    7271          654 :       tmp3 = tmp = gfc_get_cfi_desc_attribute (cfi);
    7272          654 :       if (sym->attr.allocatable || sym->attr.pointer)
    7273              :         {
    7274            6 :           int attr = (sym->attr.pointer ? CFI_attribute_pointer
    7275              :                                         : CFI_attribute_allocatable);
    7276           12 :           msg = xasprintf ("Invalid attribute %%d (expected %d) in CFI "
    7277              :                            "descriptor passed to dummy argument %s with %s "
    7278              :                            "attribute", attr, sym->name,
    7279              :                            sym->attr.pointer ? "pointer" : "allocatable");
    7280            6 :           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7281            6 :                                  tmp, build_int_cst (TREE_TYPE (tmp), attr));
    7282            6 :         }
    7283              :       else
    7284              :         {
    7285          648 :           int amin = MIN (CFI_attribute_pointer,
    7286              :                           MIN (CFI_attribute_allocatable, CFI_attribute_other));
    7287          648 :           int amax = MAX (CFI_attribute_pointer,
    7288              :                           MAX (CFI_attribute_allocatable, CFI_attribute_other));
    7289          648 :           msg = xasprintf ("Invalid attribute %%d (expected %d..%d) in CFI "
    7290              :                            "descriptor passed to nonallocatable, nonpointer "
    7291              :                            "dummy argument %s", amin, amax, sym->name);
    7292          648 :           tmp2 = tmp;
    7293          648 :           tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, tmp,
    7294          648 :                              build_int_cst (TREE_TYPE (tmp), amin));
    7295          648 :           tmp2 = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp2,
    7296          648 :                              build_int_cst (TREE_TYPE (tmp2), amax));
    7297          648 :           tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
    7298              :                                  boolean_type_node, tmp, tmp2);
    7299          648 :           gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
    7300              :                                    msg, tmp3);
    7301          648 :           free (msg);
    7302          648 :           msg = xasprintf ("Invalid unallocatated/unassociated CFI "
    7303              :                            "descriptor passed to nonallocatable, nonpointer "
    7304              :                            "dummy argument %s", sym->name);
    7305          648 :           tmp3 = tmp = gfc_get_cfi_desc_base_addr (cfi),
    7306          648 :           tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
    7307              :                                  tmp, null_pointer_node);
    7308              :         }
    7309          654 :       gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
    7310              :                                msg, tmp3);
    7311          654 :       free (msg);
    7312              : 
    7313          654 :       if (sym->ts.type != BT_ASSUMED)
    7314              :         {
    7315          654 :           int type = CFI_type_other;
    7316          654 :           if (sym->ts.f90_type == BT_VOID)
    7317              :             {
    7318            0 :               type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
    7319            0 :                       ? CFI_type_cfunptr : CFI_type_cptr);
    7320              :             }
    7321              :           else
    7322          654 :             switch (sym->ts.type)
    7323              :               {
    7324            6 :                 case BT_INTEGER:
    7325            6 :                 case BT_LOGICAL:
    7326            6 :                 case BT_REAL:
    7327            6 :                 case BT_COMPLEX:
    7328            6 :                   type = CFI_type_from_type_kind (sym->ts.type, sym->ts.kind);
    7329            6 :                   break;
    7330          648 :                 case BT_CHARACTER:
    7331          648 :                   type = CFI_type_from_type_kind (CFI_type_Character,
    7332              :                                                   sym->ts.kind);
    7333          648 :                   break;
    7334            0 :                 case BT_DERIVED:
    7335            0 :                   type = CFI_type_struct;
    7336            0 :                   break;
    7337            0 :                 case BT_VOID:
    7338            0 :                   type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
    7339            0 :                         ? CFI_type_cfunptr : CFI_type_cptr);
    7340              :                   break;
    7341              : 
    7342            0 :               case BT_UNSIGNED:
    7343            0 :                 gfc_internal_error ("Unsigned not yet implemented");
    7344              : 
    7345            0 :                 case BT_ASSUMED:
    7346            0 :                 case BT_CLASS:
    7347            0 :                 case BT_PROCEDURE:
    7348            0 :                 case BT_HOLLERITH:
    7349            0 :                 case BT_UNION:
    7350            0 :                 case BT_BOZ:
    7351            0 :                 case BT_UNKNOWN:
    7352            0 :                   gcc_unreachable ();
    7353              :             }
    7354          654 :           msg = xasprintf ("Unexpected type %%d (expected %d) in CFI descriptor"
    7355              :                            " passed to dummy argument %s", type, sym->name);
    7356          654 :           tmp2 = tmp = gfc_get_cfi_desc_type (cfi);
    7357          654 :           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7358          654 :                                  tmp, build_int_cst (TREE_TYPE (tmp), type));
    7359          654 :           gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
    7360              :                                msg, tmp2);
    7361          654 :           free (msg);
    7362              :         }
    7363              :     }
    7364              : 
    7365         1819 :   if (!sym->attr.referenced)
    7366           72 :     goto done;
    7367              : 
    7368              :   /* Set string length for len=* and len=:, otherwise, it is already set.  */
    7369         1747 :   if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
    7370              :     {
    7371          647 :       tmp = fold_convert (gfc_array_index_type,
    7372              :                           gfc_get_cfi_desc_elem_len (cfi));
    7373          647 :       if (sym->ts.kind != 1)
    7374          197 :         tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
    7375              :                                gfc_array_index_type, tmp,
    7376              :                                build_int_cst (gfc_charlen_type_node,
    7377          197 :                                               sym->ts.kind));
    7378          647 :       gfc_add_modify (&block, sym->ts.u.cl->backend_decl, tmp);
    7379              :     }
    7380              : 
    7381         1747 :   if (sym->ts.type == BT_CHARACTER
    7382         1020 :       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
    7383              :     {
    7384          804 :       gfc_conv_string_length (sym->ts.u.cl, NULL, &block);
    7385          804 :       gfc_trans_vla_type_sizes (sym, &block);
    7386              :     }
    7387              : 
    7388              :   /* gfc->data = cfi->base_addr - or for scalars: gfc = cfi->base_addr.
    7389              :      assumed-size/explicit-size arrays end up here for character(len=*)
    7390              :      only. */
    7391         1747 :   if (!sym->attr.dimension || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7392              :     {
    7393          418 :       tmp = gfc_get_cfi_desc_base_addr (cfi);
    7394          418 :       gfc_add_modify (&block, gfc_desc,
    7395          418 :                       fold_convert (TREE_TYPE (gfc_desc), tmp));
    7396          418 :       if (!sym->attr.dimension)
    7397          164 :         goto done;
    7398              :     }
    7399              : 
    7400         1583 :   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7401              :     {
    7402              :       /* gfc->dtype = ... (from declaration, not from cfi).  */
    7403         1329 :       etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
    7404         1329 :       gfc_add_modify (&block, gfc_conv_descriptor_dtype (gfc_desc),
    7405         1329 :                       gfc_get_dtype_rank_type (sym->as->rank, etype));
    7406              :       /* gfc->data = cfi->base_addr. */
    7407         1329 :       gfc_conv_descriptor_data_set (&block, gfc_desc,
    7408              :                                     gfc_get_cfi_desc_base_addr (cfi));
    7409              :     }
    7410              : 
    7411         1583 :   if (sym->ts.type == BT_ASSUMED)
    7412              :     {
    7413              :       /* For type(*), take elem_len + dtype.type from the actual argument.  */
    7414           19 :       gfc_add_modify (&block, gfc_conv_descriptor_elem_len (gfc_desc),
    7415              :                       gfc_get_cfi_desc_elem_len (cfi));
    7416           19 :       tree cond;
    7417           19 :       tree ctype = gfc_get_cfi_desc_type (cfi);
    7418           19 :       ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
    7419           19 :                                ctype, build_int_cst (TREE_TYPE (ctype),
    7420              :                                                      CFI_type_mask));
    7421           19 :       tree type = gfc_conv_descriptor_type (gfc_desc);
    7422              : 
    7423              :       /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
    7424              :       /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
    7425           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7426           19 :                               build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
    7427           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
    7428           19 :                              build_int_cst (TREE_TYPE (type), BT_VOID));
    7429           19 :       tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
    7430              :                               type,
    7431           19 :                               build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
    7432           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7433              :                               tmp, tmp2);
    7434              :       /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
    7435           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7436           19 :                               build_int_cst (TREE_TYPE (ctype),
    7437              :                                              CFI_type_struct));
    7438           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
    7439           19 :                              build_int_cst (TREE_TYPE (type), BT_DERIVED));
    7440           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7441              :                               tmp, tmp2);
    7442              :       /* if (CFI_type_Character) BT_CHARACTER else  < tmp2 >  */
    7443              :       /* Note: this is kind=1, CFI_type_ucs4_char is handled in the 'else if'
    7444              :          before (see below, as generated bottom up).  */
    7445           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7446           19 :                               build_int_cst (TREE_TYPE (ctype),
    7447              :                               CFI_type_Character));
    7448           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
    7449           19 :                              build_int_cst (TREE_TYPE (type), BT_CHARACTER));
    7450           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7451              :                               tmp, tmp2);
    7452              :       /* if (CFI_type_ucs4_char) BT_CHARACTER else  < tmp2 >  */
    7453              :       /* Note: gfc->elem_len = cfi->elem_len/4.  */
    7454              :       /* However, assuming that CFI_type_ucs4_char cannot be recovered, leave
    7455              :          gfc->elem_len == cfi->elem_len, which helps with operations which use
    7456              :          sizeof() in Fortran and cfi->elem_len in C.  */
    7457           19 :       tmp = gfc_get_cfi_desc_type (cfi);
    7458           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
    7459           19 :                               build_int_cst (TREE_TYPE (tmp),
    7460              :                                              CFI_type_ucs4_char));
    7461           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
    7462           19 :                              build_int_cst (TREE_TYPE (type), BT_CHARACTER));
    7463           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7464              :                               tmp, tmp2);
    7465              :       /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else  < tmp2 >  */
    7466           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7467           19 :                               build_int_cst (TREE_TYPE (ctype),
    7468              :                               CFI_type_Complex));
    7469           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
    7470           19 :                              build_int_cst (TREE_TYPE (type), BT_COMPLEX));
    7471           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7472              :                               tmp, tmp2);
    7473              :       /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
    7474              :            ctype else  <tmp2>  */
    7475           19 :       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7476           19 :                               build_int_cst (TREE_TYPE (ctype),
    7477              :                                              CFI_type_Integer));
    7478           19 :       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7479           19 :                               build_int_cst (TREE_TYPE (ctype),
    7480              :                                              CFI_type_Logical));
    7481           19 :       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
    7482              :                               cond, tmp);
    7483           19 :       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
    7484           19 :                               build_int_cst (TREE_TYPE (ctype),
    7485              :                                              CFI_type_Real));
    7486           19 :       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
    7487              :                               cond, tmp);
    7488           19 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
    7489           19 :                              type, fold_convert (TREE_TYPE (type), ctype));
    7490           19 :       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
    7491              :                               tmp, tmp2);
    7492           19 :       gfc_add_expr_to_block (&block, tmp2);
    7493              :     }
    7494              : 
    7495         1583 :   if (sym->as->rank < 0)
    7496              :     {
    7497              :       /* Set gfc->dtype.rank, if assumed-rank.  */
    7498          587 :       rank = gfc_get_cfi_desc_rank (cfi);
    7499          587 :       gfc_add_modify (&block, gfc_conv_descriptor_rank (gfc_desc), rank);
    7500              :     }
    7501          996 :   else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7502              :     /* In that case, the CFI rank and the declared rank can differ.  */
    7503          254 :     rank = gfc_get_cfi_desc_rank (cfi);
    7504              :   else
    7505          742 :     rank = build_int_cst (signed_char_type_node, sym->as->rank);
    7506              : 
    7507              :   /* With bind(C), the standard requires that both Fortran callers and callees
    7508              :      handle noncontiguous arrays passed to an dummy with 'contiguous' attribute
    7509              :      and with character(len=*) + assumed-size/explicit-size arrays.
    7510              :      cf. Fortran 2018, 18.3.6, paragraph 5 (and for the caller: para. 6). */
    7511         1583 :   if ((sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length
    7512          550 :        && (sym->as->type == AS_ASSUMED_SIZE || sym->as->type == AS_EXPLICIT))
    7513         1329 :       || sym->attr.contiguous)
    7514              :     {
    7515          517 :       do_copy_inout = true;
    7516          517 :       gcc_assert (!sym->attr.pointer);
    7517          517 :       stmtblock_t block2;
    7518          517 :       tree data;
    7519          517 :       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7520          263 :         data = gfc_conv_descriptor_data_get (gfc_desc);
    7521          254 :       else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
    7522            0 :         data = gfc_build_addr_expr (NULL, gfc_desc);
    7523              :       else
    7524              :         data = gfc_desc;
    7525              : 
    7526              :       /* Is copy-in/out needed? */
    7527              :       /* do_copyin = rank != 0 && !assumed-size */
    7528          517 :       tree cond_var = gfc_create_var (boolean_type_node, "do_copyin");
    7529          517 :       tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7530          517 :                                    rank, build_zero_cst (TREE_TYPE (rank)));
    7531              :       /* dim[rank-1].extent != -1 -> assumed size*/
    7532          517 :       tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (rank),
    7533          517 :                              rank, build_int_cst (TREE_TYPE (rank), 1));
    7534          517 :       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7535              :                               gfc_get_cfi_dim_extent (cfi, tmp),
    7536              :                               build_int_cst (gfc_array_index_type, -1));
    7537          517 :       cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
    7538              :                               boolean_type_node, cond, tmp);
    7539          517 :       gfc_add_modify (&block, cond_var, cond);
    7540              :       /* if (do_copyin) do_copyin = ... || ... || ... */
    7541          517 :       gfc_init_block (&block2);
    7542              :       /* dim[0].sm != elem_len */
    7543          517 :       tmp = fold_convert (gfc_array_index_type,
    7544              :                           gfc_get_cfi_desc_elem_len (cfi));
    7545          517 :       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7546              :                               gfc_get_cfi_dim_sm (cfi, gfc_index_zero_node),
    7547              :                               tmp);
    7548          517 :       gfc_add_modify (&block2, cond_var, cond);
    7549              : 
    7550              :       /* for (i = 1; i < rank; ++i)
    7551              :            cond &&= dim[i].sm != (dv->dim[i - 1].sm * dv->dim[i - 1].extent) */
    7552          517 :       idx = gfc_create_var (TREE_TYPE (rank), "idx");
    7553          517 :       stmtblock_t loop_body;
    7554          517 :       gfc_init_block (&loop_body);
    7555          517 :       tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
    7556          517 :                              idx, build_int_cst (TREE_TYPE (idx), 1));
    7557          517 :       tree tmp2 = gfc_get_cfi_dim_sm (cfi, tmp);
    7558          517 :       tmp = gfc_get_cfi_dim_extent (cfi, tmp);
    7559          517 :       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
    7560              :                              tmp2, tmp);
    7561          517 :       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7562              :                              gfc_get_cfi_dim_sm (cfi, idx), tmp);
    7563          517 :       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
    7564              :                               cond_var, cond);
    7565          517 :       gfc_add_modify (&loop_body, cond_var, cond);
    7566         1034 :       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
    7567          517 :                           rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
    7568              :                           gfc_finish_block (&loop_body));
    7569          517 :       tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
    7570              :                       build_empty_stmt (input_location));
    7571          517 :       gfc_add_expr_to_block (&block, tmp);
    7572              : 
    7573              :       /* Copy-in body.  */
    7574          517 :       gfc_init_block (&block2);
    7575              :       /* size = dim[0].extent; for (i = 1; i < rank; ++i) size *= dim[i].extent */
    7576          517 :       size_var = gfc_create_var (size_type_node, "size");
    7577          517 :       tmp = fold_convert (size_type_node,
    7578              :                           gfc_get_cfi_dim_extent (cfi, gfc_index_zero_node));
    7579          517 :       gfc_add_modify (&block2, size_var, tmp);
    7580              : 
    7581          517 :       gfc_init_block (&loop_body);
    7582          517 :       tmp = fold_convert (size_type_node,
    7583              :                           gfc_get_cfi_dim_extent (cfi, idx));
    7584          517 :       tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
    7585              :                              size_var, fold_convert (size_type_node, tmp));
    7586          517 :       gfc_add_modify (&loop_body, size_var, tmp);
    7587         1034 :       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
    7588          517 :                           rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
    7589              :                           gfc_finish_block (&loop_body));
    7590              :       /* data = malloc (size * elem_len) */
    7591          517 :       tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
    7592              :                              size_var, gfc_get_cfi_desc_elem_len (cfi));
    7593          517 :       tree call = builtin_decl_explicit (BUILT_IN_MALLOC);
    7594          517 :       call = build_call_expr_loc (input_location, call, 1, tmp);
    7595          517 :       gfc_add_modify (&block2, data, fold_convert (TREE_TYPE (data), call));
    7596              : 
    7597              :       /* Copy the data:
    7598              :          for (idx = 0; idx < size; ++idx)
    7599              :            {
    7600              :              shift = 0;
    7601              :              tmpidx = idx
    7602              :              for (dim = 0; dim < rank; ++dim)
    7603              :                 {
    7604              :                   shift += (tmpidx % extent[d]) * sm[d]
    7605              :                   tmpidx = tmpidx / extend[d]
    7606              :                 }
    7607              :              memcpy (lhs + idx*elem_len, rhs + shift, elem_len)
    7608              :            } .*/
    7609          517 :       idx = gfc_create_var (size_type_node, "arrayidx");
    7610          517 :       gfc_init_block (&loop_body);
    7611          517 :       tree shift = gfc_create_var (size_type_node, "shift");
    7612          517 :       tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
    7613          517 :       gfc_add_modify (&loop_body, shift, build_zero_cst (TREE_TYPE (shift)));
    7614          517 :       gfc_add_modify (&loop_body, tmpidx, idx);
    7615          517 :       stmtblock_t inner_loop;
    7616          517 :       gfc_init_block (&inner_loop);
    7617          517 :       tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
    7618              :       /* shift += (tmpidx % extent[d]) * sm[d] */
    7619          517 :       tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
    7620              :                              size_type_node, tmpidx,
    7621              :                              fold_convert (size_type_node,
    7622              :                                            gfc_get_cfi_dim_extent (cfi, dim)));
    7623          517 :       tmp = fold_build2_loc (input_location, MULT_EXPR,
    7624              :                              size_type_node, tmp,
    7625              :                              fold_convert (size_type_node,
    7626              :                                            gfc_get_cfi_dim_sm (cfi, dim)));
    7627          517 :       gfc_add_modify (&inner_loop, shift,
    7628              :                       fold_build2_loc (input_location, PLUS_EXPR,
    7629              :                                        size_type_node, shift, tmp));
    7630              :       /* tmpidx = tmpidx / extend[d] */
    7631          517 :       tmp = fold_convert (size_type_node, gfc_get_cfi_dim_extent (cfi, dim));
    7632          517 :       gfc_add_modify (&inner_loop, tmpidx,
    7633              :                       fold_build2_loc (input_location, TRUNC_DIV_EXPR,
    7634              :                                        size_type_node, tmpidx, tmp));
    7635         1034 :       gfc_simple_for_loop (&loop_body, dim, build_zero_cst (TREE_TYPE (rank)),
    7636          517 :                            rank, LT_EXPR, build_int_cst (TREE_TYPE (dim), 1),
    7637              :                            gfc_finish_block (&inner_loop));
    7638              :       /* Assign.  */
    7639          517 :       tmp = fold_convert (pchar_type_node, gfc_get_cfi_desc_base_addr (cfi));
    7640          517 :       tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
    7641          517 :       tree lhs;
    7642              :       /* memcpy (lhs + idx*elem_len, rhs + shift, elem_len)  */
    7643          517 :       tree elem_len;
    7644          517 :       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7645          263 :         elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
    7646              :       else
    7647          254 :         elem_len = gfc_get_cfi_desc_elem_len (cfi);
    7648          517 :       lhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
    7649              :                              elem_len, idx);
    7650          517 :       lhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR, pchar_type_node,
    7651              :                              fold_convert (pchar_type_node, data), lhs);
    7652          517 :       tmp = fold_convert (pvoid_type_node, tmp);
    7653          517 :       lhs = fold_convert (pvoid_type_node, lhs);
    7654          517 :       call = builtin_decl_explicit (BUILT_IN_MEMCPY);
    7655          517 :       call = build_call_expr_loc (input_location, call, 3, lhs, tmp, elem_len);
    7656          517 :       gfc_add_expr_to_block (&loop_body, fold_convert (void_type_node, call));
    7657         1034 :       gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
    7658          517 :                            size_var, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
    7659              :                            gfc_finish_block (&loop_body));
    7660              :       /* if (cond) { block2 }  */
    7661          517 :       tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
    7662              :                       build_empty_stmt (input_location));
    7663          517 :       gfc_add_expr_to_block (&block, tmp);
    7664              :     }
    7665              : 
    7666         1583 :   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7667              :     {
    7668          254 :       tree offset, type;
    7669          254 :       type = TREE_TYPE (gfc_desc);
    7670          254 :       gfc_trans_array_bounds (type, sym, &offset, &block);
    7671          254 :       if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
    7672          144 :         gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
    7673          254 :       goto done;
    7674              :     }
    7675              : 
    7676              :   /* If cfi->data != NULL. */
    7677         1329 :   stmtblock_t block2;
    7678         1329 :   gfc_init_block (&block2);
    7679              : 
    7680              :   /* if do_copy_inout:  gfc->dspan = gfc->dtype.elem_len
    7681              :      We use gfc instead of cfi on the RHS as this might be a constant.  */
    7682         1329 :   tmp = fold_convert (gfc_array_index_type,
    7683              :                       gfc_conv_descriptor_elem_len (gfc_desc));
    7684         1329 :   if (!do_copy_inout)
    7685              :     {
    7686              :       /* gfc->dspan = ((cfi->dim[0].sm % gfc->elem_len)
    7687              :                        ? cfi->dim[0].sm : gfc->elem_len).  */
    7688         1066 :       tree cond;
    7689         1066 :       tree tmp2 = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
    7690         1066 :       cond = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
    7691              :                               gfc_array_index_type, tmp2, tmp);
    7692         1066 :       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7693              :                               cond, gfc_index_zero_node);
    7694         1066 :       tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
    7695              :                         tmp2, tmp);
    7696              :     }
    7697         1329 :   gfc_conv_descriptor_span_set (&block2, gfc_desc, tmp);
    7698              : 
    7699              :   /* Calculate offset + set lbound, ubound and stride.  */
    7700         1329 :   gfc_conv_descriptor_offset_set (&block2, gfc_desc, gfc_index_zero_node);
    7701         1329 :   if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
    7702         1274 :     for (int i = 0; i < sym->as->rank; ++i)
    7703              :       {
    7704          718 :         gfc_se se;
    7705          718 :         gfc_init_se (&se, NULL );
    7706          718 :         if (sym->as->lower[i])
    7707              :           {
    7708          718 :             gfc_conv_expr (&se, sym->as->lower[i]);
    7709          718 :             tmp = se.expr;
    7710              :           }
    7711              :         else
    7712            0 :           tmp = gfc_index_one_node;
    7713          718 :         gfc_add_block_to_block (&block2, &se.pre);
    7714          718 :         gfc_conv_descriptor_lbound_set (&block2, gfc_desc, gfc_rank_cst[i],
    7715              :                                         tmp);
    7716          718 :         gfc_add_block_to_block (&block2, &se.post);
    7717              :       }
    7718              : 
    7719              :   /* Loop: for (i = 0; i < rank; ++i).  */
    7720         1329 :   idx = gfc_create_var (TREE_TYPE (rank), "idx");
    7721              : 
    7722              :   /* Loop body.  */
    7723         1329 :   stmtblock_t loop_body;
    7724         1329 :   gfc_init_block (&loop_body);
    7725              :   /* gfc->dim[i].lbound = ... */
    7726         1329 :   if (sym->attr.pointer || sym->attr.allocatable)
    7727              :     {
    7728          276 :       tmp = gfc_get_cfi_dim_lbound (cfi, idx);
    7729          276 :       gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx, tmp);
    7730              :     }
    7731         1053 :   else if (sym->as->rank < 0)
    7732          497 :     gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx,
    7733              :                                     gfc_index_one_node);
    7734              : 
    7735              :   /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
    7736         1329 :   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
    7737              :                              gfc_conv_descriptor_lbound_get (gfc_desc, idx),
    7738              :                              gfc_index_one_node);
    7739         1329 :   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
    7740              :                              gfc_get_cfi_dim_extent (cfi, idx), tmp);
    7741         1329 :   gfc_conv_descriptor_ubound_set (&loop_body, gfc_desc, idx, tmp);
    7742              : 
    7743         1329 :   if (do_copy_inout)
    7744              :     {
    7745              :       /* gfc->dim[i].stride
    7746              :            = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
    7747          263 :       tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
    7748          263 :                                    idx, build_zero_cst (TREE_TYPE (idx)));
    7749          263 :       tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
    7750          263 :                              idx, build_int_cst (TREE_TYPE (idx), 1));
    7751          263 :       tree tmp2 = gfc_get_cfi_dim_extent (cfi, tmp);
    7752          263 :       tmp = gfc_conv_descriptor_stride_get (gfc_desc, tmp);
    7753          263 :       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp2),
    7754              :                              tmp2, tmp);
    7755          263 :       tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
    7756              :                         gfc_index_one_node, tmp);
    7757              :     }
    7758              :   else
    7759              :     {
    7760              :       /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
    7761         1066 :       tmp = gfc_get_cfi_dim_sm (cfi, idx);
    7762         1066 :       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
    7763              :                              gfc_array_index_type, tmp,
    7764              :                              fold_convert (gfc_array_index_type,
    7765              :                                            gfc_get_cfi_desc_elem_len (cfi)));
    7766              :      }
    7767         1329 :   gfc_conv_descriptor_stride_set (&loop_body, gfc_desc, idx, tmp);
    7768              :   /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
    7769         1329 :   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
    7770              :                              gfc_conv_descriptor_stride_get (gfc_desc, idx),
    7771              :                              gfc_conv_descriptor_lbound_get (gfc_desc, idx));
    7772         1329 :   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
    7773              :                              gfc_conv_descriptor_offset_get (gfc_desc), tmp);
    7774         1329 :   gfc_conv_descriptor_offset_set (&loop_body, gfc_desc, tmp);
    7775              : 
    7776              :   /* Generate loop.  */
    7777         2658 :   gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
    7778         1329 :                        rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
    7779              :                        gfc_finish_block (&loop_body));
    7780         1329 :   if (sym->attr.allocatable || sym->attr.pointer)
    7781              :     {
    7782          276 :       tmp = gfc_get_cfi_desc_base_addr (cfi),
    7783          276 :       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7784              :                              tmp, null_pointer_node);
    7785          276 :       tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
    7786              :                       build_empty_stmt (input_location));
    7787          276 :       gfc_add_expr_to_block (&block, tmp);
    7788              :     }
    7789              :   else
    7790         1053 :     gfc_add_block_to_block (&block, &block2);
    7791              : 
    7792         1819 : done:
    7793              :   /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'.  */
    7794         1819 :   if (sym->attr.optional)
    7795              :     {
    7796          317 :       tree present = fold_build2_loc (input_location, NE_EXPR,
    7797              :                                       boolean_type_node, cfi_desc,
    7798              :                                       null_pointer_node);
    7799          317 :       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
    7800              :                              sym->backend_decl,
    7801          317 :                              fold_convert (TREE_TYPE (sym->backend_decl),
    7802              :                                            null_pointer_node));
    7803          317 :       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block), tmp);
    7804          317 :       gfc_add_expr_to_block (init, tmp);
    7805              :     }
    7806              :   else
    7807         1502 :     gfc_add_block_to_block (init, &block);
    7808              : 
    7809         1819 :   if (!sym->attr.referenced)
    7810          984 :     return;
    7811              : 
    7812              :   /* If pointer not changed, nothing to be done (except copy out)  */
    7813         1747 :   if (!do_copy_inout && ((!sym->attr.pointer && !sym->attr.allocatable)
    7814          381 :                          || sym->attr.intent == INTENT_IN))
    7815              :     return;
    7816              : 
    7817          835 :   gfc_init_block (&block);
    7818              : 
    7819              :   /* For bind(C), Fortran does not permit mixing 'pointer' with 'contiguous' (or
    7820              :      len=*). Thus, when copy out is needed, the bounds ofthe descriptor remain
    7821              :      unchanged.  */
    7822          835 :   if (do_copy_inout)
    7823              :     {
    7824          517 :       tree data, call;
    7825          517 :       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7826          263 :         data = gfc_conv_descriptor_data_get (gfc_desc);
    7827          254 :       else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
    7828            0 :         data = gfc_build_addr_expr (NULL, gfc_desc);
    7829              :       else
    7830              :         data = gfc_desc;
    7831          517 :       gfc_init_block (&block2);
    7832          517 :       if (sym->attr.intent != INTENT_IN)
    7833              :         {
    7834              :          /* First, create the inner copy-out loop.
    7835              :           for (idx = 0; idx < size; ++idx)
    7836              :            {
    7837              :              shift = 0;
    7838              :              tmpidx = idx
    7839              :              for (dim = 0; dim < rank; ++dim)
    7840              :                 {
    7841              :                   shift += (tmpidx % extent[d]) * sm[d]
    7842              :                   tmpidx = tmpidx / extend[d]
    7843              :                 }
    7844              :              memcpy (lhs + shift, rhs + idx*elem_len, elem_len)
    7845              :            } .*/
    7846          292 :           stmtblock_t loop_body;
    7847          292 :           idx = gfc_create_var (size_type_node, "arrayidx");
    7848          292 :           gfc_init_block (&loop_body);
    7849          292 :           tree shift = gfc_create_var (size_type_node, "shift");
    7850          292 :           tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
    7851          292 :           gfc_add_modify (&loop_body, shift,
    7852          292 :                           build_zero_cst (TREE_TYPE (shift)));
    7853          292 :           gfc_add_modify (&loop_body, tmpidx, idx);
    7854          292 :           stmtblock_t inner_loop;
    7855          292 :           gfc_init_block (&inner_loop);
    7856          292 :           tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
    7857              :           /* shift += (tmpidx % extent[d]) * sm[d] */
    7858          292 :           tmp = fold_convert (size_type_node,
    7859              :                               gfc_get_cfi_dim_extent (cfi, dim));
    7860          292 :           tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
    7861              :                                  size_type_node, tmpidx, tmp);
    7862          292 :           tmp = fold_build2_loc (input_location, MULT_EXPR,
    7863              :                                  size_type_node, tmp,
    7864              :                                  fold_convert (size_type_node,
    7865              :                                                gfc_get_cfi_dim_sm (cfi, dim)));
    7866          292 :           gfc_add_modify (&inner_loop, shift,
    7867              :                       fold_build2_loc (input_location, PLUS_EXPR,
    7868              :                                        size_type_node, shift, tmp));
    7869              :           /* tmpidx = tmpidx / extend[d] */
    7870          292 :           tmp = fold_convert (size_type_node,
    7871              :                               gfc_get_cfi_dim_extent (cfi, dim));
    7872          292 :           gfc_add_modify (&inner_loop, tmpidx,
    7873              :                           fold_build2_loc (input_location, TRUNC_DIV_EXPR,
    7874              :                                            size_type_node, tmpidx, tmp));
    7875          876 :           gfc_simple_for_loop (&loop_body, dim,
    7876          292 :                                build_zero_cst (TREE_TYPE (rank)), rank, LT_EXPR,
    7877          292 :                                build_int_cst (TREE_TYPE (dim), 1),
    7878              :                                gfc_finish_block (&inner_loop));
    7879              :           /* Assign.  */
    7880          292 :           tree rhs;
    7881          292 :           tmp = fold_convert (pchar_type_node,
    7882              :                               gfc_get_cfi_desc_base_addr (cfi));
    7883          292 :           tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
    7884              :           /* memcpy (lhs + shift, rhs + idx*elem_len, elem_len) */
    7885          292 :           tree elem_len;
    7886          292 :           if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
    7887          153 :             elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
    7888              :           else
    7889          139 :             elem_len = gfc_get_cfi_desc_elem_len (cfi);
    7890          292 :           rhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
    7891              :                                  elem_len, idx);
    7892          292 :           rhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR,
    7893              :                                  pchar_type_node,
    7894              :                                  fold_convert (pchar_type_node, data), rhs);
    7895          292 :           tmp = fold_convert (pvoid_type_node, tmp);
    7896          292 :           rhs = fold_convert (pvoid_type_node, rhs);
    7897          292 :           call = builtin_decl_explicit (BUILT_IN_MEMCPY);
    7898          292 :           call = build_call_expr_loc (input_location, call, 3, tmp, rhs,
    7899              :                                       elem_len);
    7900          292 :           gfc_add_expr_to_block (&loop_body,
    7901              :                                  fold_convert (void_type_node, call));
    7902          584 :           gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
    7903              :                                size_var, LT_EXPR,
    7904          292 :                                build_int_cst (TREE_TYPE (idx), 1),
    7905              :                                gfc_finish_block (&loop_body));
    7906              :         }
    7907          517 :       call = builtin_decl_explicit (BUILT_IN_FREE);
    7908          517 :       call = build_call_expr_loc (input_location, call, 1, data);
    7909          517 :       gfc_add_expr_to_block (&block2, call);
    7910              : 
    7911              :       /* if (cfi->base_addr != gfc->data) { copy out; free(var) }; return  */
    7912          517 :       tree tmp2 = gfc_get_cfi_desc_base_addr (cfi);
    7913          517 :       tmp2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7914          517 :                               tmp2, fold_convert (TREE_TYPE (tmp2), data));
    7915          517 :       tmp = build3_v (COND_EXPR, tmp2, gfc_finish_block (&block2),
    7916              :                       build_empty_stmt (input_location));
    7917          517 :       gfc_add_expr_to_block (&block, tmp);
    7918          517 :       goto done_finally;
    7919              :     }
    7920              : 
    7921              :   /* Update pointer + array data data on exit.  */
    7922          318 :   tmp = gfc_get_cfi_desc_base_addr (cfi);
    7923          318 :   tmp2 = (!sym->attr.dimension
    7924          318 :                ? gfc_desc : gfc_conv_descriptor_data_get (gfc_desc));
    7925          318 :   gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
    7926              : 
    7927              :   /* Set string length for len=:, only.  */
    7928          318 :   if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
    7929              :     {
    7930           60 :       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
    7931           60 :       tmp = fold_convert (TREE_TYPE (tmp2), sym->ts.u.cl->backend_decl);
    7932           60 :       if (sym->ts.kind != 1)
    7933           48 :         tmp = fold_build2_loc (input_location, MULT_EXPR,
    7934           24 :                                TREE_TYPE (tmp2), tmp,
    7935           24 :                                build_int_cst (TREE_TYPE (tmp2), sym->ts.kind));
    7936           60 :       gfc_add_modify (&block, tmp2, tmp);
    7937              :     }
    7938              : 
    7939          318 :   if (!sym->attr.dimension)
    7940          102 :     goto done_finally;
    7941              : 
    7942          216 :   gfc_init_block (&block2);
    7943              : 
    7944              :   /* Loop: for (i = 0; i < rank; ++i).  */
    7945          216 :   idx = gfc_create_var (TREE_TYPE (rank), "idx");
    7946              : 
    7947              :   /* Loop body.  */
    7948          216 :   gfc_init_block (&loop_body);
    7949              :   /* cfi->dim[i].lower_bound = gfc->dim[i].lbound */
    7950          216 :   gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx),
    7951              :                   gfc_conv_descriptor_lbound_get (gfc_desc, idx));
    7952              :   /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1.  */
    7953          216 :   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
    7954              :                              gfc_conv_descriptor_ubound_get (gfc_desc, idx),
    7955              :                              gfc_conv_descriptor_lbound_get (gfc_desc, idx));
    7956          216 :   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp,
    7957              :                          gfc_index_one_node);
    7958          216 :   gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
    7959              :   /* d->dim[n].sm = gfc->dim[i].stride  * gfc->span); */
    7960          216 :   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
    7961              :                              gfc_conv_descriptor_stride_get (gfc_desc, idx),
    7962              :                              gfc_conv_descriptor_span_get (gfc_desc));
    7963          216 :   gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
    7964              : 
    7965              :   /* Generate loop.  */
    7966          432 :   gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
    7967          216 :                        rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
    7968              :                        gfc_finish_block (&loop_body));
    7969              :   /* if (gfc->data != NULL) { block2 }.  */
    7970          216 :   tmp = gfc_get_cfi_desc_base_addr (cfi),
    7971          216 :   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
    7972              :                          tmp, null_pointer_node);
    7973          216 :   tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
    7974              :                   build_empty_stmt (input_location));
    7975          216 :   gfc_add_expr_to_block (&block, tmp);
    7976              : 
    7977          835 : done_finally:
    7978              :   /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'.  */
    7979          835 :   if (sym->attr.optional)
    7980              :     {
    7981          180 :       tree present = fold_build2_loc (input_location, NE_EXPR,
    7982              :                                       boolean_type_node, cfi_desc,
    7983              :                                       null_pointer_node);
    7984          180 :       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
    7985              :                       build_empty_stmt (input_location));
    7986          180 :       gfc_add_expr_to_block (finally, tmp);
    7987              :      }
    7988              :    else
    7989          655 :      gfc_add_block_to_block (finally, &block);
    7990              : }
    7991              : 
    7992              : 
    7993              : static void
    7994          233 : emit_not_set_warning (gfc_symbol *sym)
    7995              : {
    7996          233 :   if (warn_return_type > 0 && sym == sym->result)
    7997           17 :     gfc_warning (OPT_Wreturn_type,
    7998              :                  "Return value of function %qs at %L not set",
    7999              :                  sym->name, &sym->declared_at);
    8000          233 :   if (warn_return_type > 0)
    8001           22 :     suppress_warning (sym->backend_decl);
    8002          233 : }
    8003              : 
    8004              : 
    8005              : /* Generate code for a function.  */
    8006              : 
    8007              : void
    8008        84311 : gfc_generate_function_code (gfc_namespace * ns)
    8009              : {
    8010        84311 :   tree fndecl;
    8011        84311 :   tree old_context;
    8012        84311 :   tree decl;
    8013        84311 :   tree tmp;
    8014        84311 :   tree fpstate = NULL_TREE;
    8015        84311 :   stmtblock_t init, cleanup, outer_block;
    8016        84311 :   stmtblock_t body;
    8017        84311 :   gfc_wrapped_block try_block;
    8018        84311 :   tree recurcheckvar = NULL_TREE;
    8019        84311 :   gfc_symbol *sym;
    8020        84311 :   gfc_symbol *previous_procedure_symbol;
    8021        84311 :   int rank, ieee;
    8022        84311 :   bool is_recursive;
    8023              : 
    8024        84311 :   sym = ns->proc_name;
    8025        84311 :   previous_procedure_symbol = current_procedure_symbol;
    8026        84311 :   current_procedure_symbol = sym;
    8027              : 
    8028              :   /* Initialize sym->tlink so that gfc_trans_deferred_vars does not get
    8029              :      lost or worse.  */
    8030        84311 :   sym->tlink = sym;
    8031              : 
    8032              :   /* Create the declaration for functions with global scope.  */
    8033        84311 :   if (!sym->backend_decl)
    8034        35171 :     gfc_create_function_decl (ns, false);
    8035              : 
    8036        84311 :   fndecl = sym->backend_decl;
    8037        84311 :   old_context = current_function_decl;
    8038              : 
    8039        84311 :   if (old_context)
    8040              :     {
    8041        22902 :       push_function_context ();
    8042        22902 :       saved_parent_function_decls = saved_function_decls;
    8043        22902 :       saved_function_decls = NULL_TREE;
    8044              :     }
    8045              : 
    8046        84311 :   trans_function_start (sym);
    8047        84311 :   gfc_current_locus = sym->declared_at;
    8048              : 
    8049        84311 :   gfc_init_block (&init);
    8050        84311 :   gfc_init_block (&cleanup);
    8051        84311 :   gfc_init_block (&outer_block);
    8052              : 
    8053        84311 :   if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER)
    8054              :     {
    8055              :       /* Copy length backend_decls to all entry point result
    8056              :          symbols.  */
    8057           50 :       gfc_entry_list *el;
    8058           50 :       tree backend_decl;
    8059              : 
    8060           50 :       gfc_conv_const_charlen (ns->proc_name->ts.u.cl);
    8061           50 :       backend_decl = ns->proc_name->result->ts.u.cl->backend_decl;
    8062          186 :       for (el = ns->entries; el; el = el->next)
    8063          136 :         el->sym->result->ts.u.cl->backend_decl = backend_decl;
    8064              :     }
    8065              : 
    8066              :   /* Translate COMMON blocks.  */
    8067        84311 :   gfc_trans_common (ns);
    8068              : 
    8069              :   /* Null the parent fake result declaration if this namespace is
    8070              :      a module function or an external procedures.  */
    8071        84311 :   if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
    8072        58847 :         || ns->parent == NULL)
    8073        61409 :     parent_fake_result_decl = NULL_TREE;
    8074              : 
    8075              :   /* For BIND(C):
    8076              :      - deallocate intent-out allocatable dummy arguments.
    8077              :      - Create GFC variable which will later be populated by convert_CFI_desc  */
    8078        84311 :   if (sym->attr.is_bind_c)
    8079         1893 :     for (gfc_formal_arglist *formal = gfc_sym_get_dummy_args (sym);
    8080         5905 :          formal; formal = formal->next)
    8081              :       {
    8082         4012 :         gfc_symbol *fsym = formal->sym;
    8083         4012 :         if (!is_CFI_desc (fsym, NULL))
    8084         2193 :           continue;
    8085         1819 :         if (!fsym->attr.referenced)
    8086              :           {
    8087           72 :             gfc_conv_cfi_to_gfc (&init, &cleanup, fsym->backend_decl,
    8088              :                                  NULL_TREE, fsym);
    8089           72 :             continue;
    8090              :           }
    8091              :         /* Let's now create a local GFI descriptor. Afterwards:
    8092              :            desc is the local descriptor,
    8093              :            desc_p is a pointer to it
    8094              :              and stored in sym->backend_decl
    8095              :            GFC_DECL_SAVED_DESCRIPTOR (desc_p) contains the CFI descriptor
    8096              :              -> PARM_DECL and before sym->backend_decl.
    8097              :            For scalars, decl == decl_p is a pointer variable.  */
    8098         1747 :         tree desc_p, desc;
    8099         1747 :         location_t loc = gfc_get_location (&sym->declared_at);
    8100         1747 :         if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length)
    8101          647 :           fsym->ts.u.cl->backend_decl = gfc_create_var (gfc_array_index_type,
    8102              :                                                         fsym->name);
    8103         1100 :         else if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->backend_decl)
    8104              :           {
    8105          157 :             gfc_se se;
    8106          157 :             gfc_init_se (&se, NULL );
    8107          157 :             gfc_conv_expr (&se, fsym->ts.u.cl->length);
    8108          157 :             gfc_add_block_to_block (&init, &se.pre);
    8109          157 :             fsym->ts.u.cl->backend_decl = se.expr;
    8110          157 :             gcc_assert(se.post.head == NULL_TREE);
    8111              :           }
    8112              :         /* Nullify, otherwise gfc_sym_type will return the CFI type.  */
    8113         1747 :         tree tmp = fsym->backend_decl;
    8114         1747 :         fsym->backend_decl = NULL;
    8115         1747 :         tree type = gfc_sym_type (fsym);
    8116         1747 :         gcc_assert (POINTER_TYPE_P (type));
    8117         1747 :         if (POINTER_TYPE_P (TREE_TYPE (type)))
    8118              :           /* For instance, allocatable scalars.  */
    8119          105 :           type = TREE_TYPE (type);
    8120         1747 :         if (TREE_CODE (type) == REFERENCE_TYPE)
    8121         1179 :           type = build_pointer_type (TREE_TYPE (type));
    8122         1747 :         desc_p = build_decl (loc, VAR_DECL, get_identifier (fsym->name), type);
    8123         1747 :         if (!fsym->attr.dimension)
    8124              :           desc = desc_p;
    8125         1583 :         else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (desc_p))))
    8126              :           {
    8127              :             /* Character(len=*) explicit-size/assumed-size array. */
    8128          254 :             desc = desc_p;
    8129          254 :             gfc_build_qualified_array (desc, fsym);
    8130              :           }
    8131              :         else
    8132              :           {
    8133         1329 :             tree size = size_in_bytes (TREE_TYPE (TREE_TYPE (desc_p)));
    8134         1329 :             tree call = builtin_decl_explicit (BUILT_IN_ALLOCA);
    8135         1329 :             call = build_call_expr_loc (input_location, call, 1, size);
    8136         1329 :             gfc_add_modify (&outer_block, desc_p,
    8137         1329 :                             fold_convert (TREE_TYPE(desc_p), call));
    8138         1329 :             desc = build_fold_indirect_ref_loc (input_location, desc_p);
    8139              :           }
    8140         1747 :         pushdecl (desc_p);
    8141         1747 :         if (fsym->attr.optional)
    8142              :           {
    8143          311 :             gfc_allocate_lang_decl (desc_p);
    8144          311 :             GFC_DECL_OPTIONAL_ARGUMENT (desc_p) = 1;
    8145              :           }
    8146         1747 :         fsym->backend_decl = desc_p;
    8147         1747 :         gfc_conv_cfi_to_gfc (&init, &cleanup, tmp, desc, fsym);
    8148              :       }
    8149              : 
    8150              :   /* For OpenMP, ensure that declare variant in INTERFACE is is processed
    8151              :      especially as some late diagnostic is only done on tree level.  */
    8152        84311 :   if (flag_openmp)
    8153         8653 :     gfc_traverse_ns (ns, gfc_handle_omp_declare_variant);
    8154              : 
    8155        84311 :   gfc_generate_contained_functions (ns);
    8156              : 
    8157        84311 :   has_coarray_vars_or_accessors = caf_accessor_head != NULL;
    8158        84311 :   generate_local_vars (ns);
    8159              : 
    8160        84311 :   if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars_or_accessors)
    8161          400 :     generate_coarray_init (ns);
    8162              : 
    8163              :   /* Keep the parent fake result declaration in module functions
    8164              :      or external procedures.  */
    8165        84311 :   if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
    8166        58847 :         || ns->parent == NULL)
    8167        61409 :     current_fake_result_decl = parent_fake_result_decl;
    8168              :   else
    8169        22902 :     current_fake_result_decl = NULL_TREE;
    8170              : 
    8171       168622 :   is_recursive = sym->attr.recursive
    8172        84311 :                  || (sym->attr.entry_master
    8173          634 :                      && sym->ns->entries->sym->attr.recursive);
    8174        84311 :   if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
    8175         1009 :       && !is_recursive && !flag_recursive && !sym->attr.artificial)
    8176              :     {
    8177          840 :       char * msg;
    8178              : 
    8179          840 :       msg = xasprintf ("Recursive call to nonrecursive procedure '%s'",
    8180              :                        sym->name);
    8181          840 :       recurcheckvar = gfc_create_var (logical_type_node, "is_recursive");
    8182          840 :       TREE_STATIC (recurcheckvar) = 1;
    8183          840 :       DECL_INITIAL (recurcheckvar) = logical_false_node;
    8184          840 :       gfc_add_expr_to_block (&init, recurcheckvar);
    8185          840 :       gfc_trans_runtime_check (true, false, recurcheckvar, &init,
    8186              :                                &sym->declared_at, msg);
    8187          840 :       gfc_add_modify (&init, recurcheckvar, logical_true_node);
    8188          840 :       free (msg);
    8189              :     }
    8190              : 
    8191              :   /* Check if an IEEE module is used in the procedure.  If so, save
    8192              :      the floating point state.  */
    8193        84311 :   ieee = is_ieee_module_used (ns);
    8194        84311 :   if (ieee)
    8195          445 :     fpstate = gfc_save_fp_state (&init);
    8196              : 
    8197              :   /* Now generate the code for the body of this function.  */
    8198        84311 :   gfc_init_block (&body);
    8199              : 
    8200        84311 :   if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
    8201        84311 :         && sym->attr.subroutine)
    8202              :     {
    8203           42 :       tree alternate_return;
    8204           42 :       alternate_return = gfc_get_fake_result_decl (sym, 0);
    8205           42 :       gfc_add_modify (&body, alternate_return, integer_zero_node);
    8206              :     }
    8207              : 
    8208        84311 :   if (ns->entries)
    8209              :     {
    8210              :       /* Jump to the correct entry point.  */
    8211          634 :       tmp = gfc_trans_entry_master_switch (ns->entries);
    8212          634 :       gfc_add_expr_to_block (&body, tmp);
    8213              :     }
    8214              : 
    8215              :   /* If bounds-checking is enabled, generate code to check passed in actual
    8216              :      arguments against the expected dummy argument attributes (e.g. string
    8217              :      lengths).  */
    8218        84311 :   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c)
    8219         2809 :     add_argument_checking (&body, sym);
    8220              : 
    8221        84311 :   finish_oacc_declare (ns, sym, false);
    8222              : 
    8223        84311 :   tmp = gfc_trans_code (ns->code);
    8224        84311 :   gfc_add_expr_to_block (&body, tmp);
    8225              : 
    8226              :   /* This permits the return value to be correctly initialized, even when the
    8227              :      function result was not referenced.  */
    8228        84311 :   if (sym->abr_modproc_decl
    8229          247 :       && IS_PDT (sym)
    8230            7 :       && !sym->attr.allocatable
    8231            7 :       && sym->result == sym
    8232        84318 :       && get_proc_result (sym) == NULL_TREE)
    8233              :     {
    8234            1 :       gfc_get_fake_result_decl (sym->result, 0);
    8235              :       /* TODO: move to the appropriate place in resolve.cc.  */
    8236            1 :       emit_not_set_warning (sym);
    8237              :     }
    8238              : 
    8239        84311 :   if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
    8240        84311 :       || (sym->result && sym->result != sym
    8241         1170 :           && sym->result->ts.type == BT_DERIVED
    8242          155 :           && sym->result->ts.u.derived->attr.alloc_comp))
    8243              :     {
    8244        12008 :       bool artificial_result_decl = false;
    8245        12008 :       tree result = get_proc_result (sym);
    8246        12008 :       gfc_symbol *rsym = sym == sym->result ? sym : sym->result;
    8247              : 
    8248              :       /* Make sure that a function returning an object with
    8249              :          alloc/pointer_components always has a result, where at least
    8250              :          the allocatable/pointer components are set to zero.  */
    8251        12008 :       if (result == NULL_TREE && sym->attr.function
    8252          232 :           && ((sym->result->ts.type == BT_DERIVED
    8253           28 :                && (sym->attr.allocatable
    8254           22 :                    || sym->attr.pointer
    8255           20 :                    || sym->result->ts.u.derived->attr.alloc_comp
    8256           20 :                    || sym->result->ts.u.derived->attr.pointer_comp))
    8257          224 :               || (sym->result->ts.type == BT_CLASS
    8258           38 :                   && (CLASS_DATA (sym->result)->attr.allocatable
    8259           11 :                       || CLASS_DATA (sym->result)->attr.class_pointer
    8260            0 :                       || CLASS_DATA (sym->result)->attr.alloc_comp
    8261            0 :                       || CLASS_DATA (sym->result)->attr.pointer_comp))))
    8262              :         {
    8263           46 :           artificial_result_decl = true;
    8264           46 :           result = gfc_get_fake_result_decl (sym->result, 0);
    8265              :         }
    8266              : 
    8267        12008 :       if (result != NULL_TREE && sym->attr.function && !sym->attr.pointer)
    8268              :         {
    8269        11392 :           if (sym->attr.allocatable && sym->attr.dimension == 0
    8270          101 :               && sym->result == sym)
    8271           75 :             gfc_add_modify (&init, result, fold_convert (TREE_TYPE (result),
    8272              :                                                          null_pointer_node));
    8273        11317 :           else if (sym->ts.type == BT_CLASS
    8274          733 :                    && CLASS_DATA (sym)->attr.allocatable
    8275          503 :                    && CLASS_DATA (sym)->attr.dimension == 0
    8276          316 :                    && sym->result == sym)
    8277              :             {
    8278          135 :               tmp = gfc_class_data_get (result);
    8279          135 :               gfc_add_modify (&init, tmp,
    8280          135 :                               fold_convert (TREE_TYPE (tmp),
    8281              :                                             null_pointer_node));
    8282          135 :               gfc_reset_vptr (&init, nullptr, result,
    8283          135 :                               sym->result->ts.u.derived);
    8284              :             }
    8285        11182 :           else if (sym->ts.type == BT_DERIVED
    8286         1225 :                    && !sym->attr.allocatable)
    8287              :             {
    8288         1200 :               gfc_expr *init_exp;
    8289              :               /* Arrays are not initialized using the default initializer of
    8290              :                  their elements.  Therefore only check if a default
    8291              :                  initializer is available when the result is scalar.  */
    8292         1200 :               init_exp = rsym->as ? NULL
    8293         1179 :                                   : gfc_generate_initializer (&rsym->ts, true);
    8294         1179 :               if (init_exp)
    8295              :                 {
    8296          636 :                   tmp = gfc_trans_structure_assign (result, init_exp, 0);
    8297          636 :                   gfc_free_expr (init_exp);
    8298          636 :                   gfc_add_expr_to_block (&init, tmp);
    8299              :                 }
    8300              : 
    8301         1200 :               if (rsym->ts.u.derived->attr.alloc_comp)
    8302              :                 {
    8303          433 :                   rank = rsym->as ? rsym->as->rank : 0;
    8304          433 :                   tmp = gfc_nullify_alloc_comp (rsym->ts.u.derived, result,
    8305              :                                                 rank);
    8306          433 :                   gfc_prepend_expr_to_block (&body, tmp);
    8307              :                 }
    8308              :             }
    8309              :         }
    8310              : 
    8311        12008 :       if (result == NULL_TREE || artificial_result_decl)
    8312              :         /* TODO: move to the appropriate place in resolve.cc.  */
    8313          232 :         emit_not_set_warning (sym);
    8314              : 
    8315          232 :       if (result != NULL_TREE)
    8316        11822 :         gfc_add_expr_to_block (&body, gfc_generate_return ());
    8317              :     }
    8318              : 
    8319              :   /* Reset recursion-check variable.  */
    8320        84311 :   if (recurcheckvar != NULL_TREE)
    8321              :     {
    8322          840 :       gfc_add_modify (&cleanup, recurcheckvar, logical_false_node);
    8323          840 :       recurcheckvar = NULL;
    8324              :     }
    8325              : 
    8326              :   /* If IEEE modules are loaded, restore the floating-point state.  */
    8327        84311 :   if (ieee)
    8328          445 :     gfc_restore_fp_state (&cleanup, fpstate);
    8329              : 
    8330              :   /* Finish the function body and add init and cleanup code.  */
    8331        84311 :   tmp = gfc_finish_block (&body);
    8332              :   /* Add code to create and cleanup arrays.  */
    8333        84311 :   gfc_start_wrapped_block (&try_block, tmp);
    8334        84311 :   gfc_trans_deferred_vars (sym, &try_block);
    8335        84311 :   gfc_add_init_cleanup (&try_block, gfc_finish_block (&init),
    8336              :                         gfc_finish_block (&cleanup));
    8337              : 
    8338              :   /* Add all the decls we created during processing.  */
    8339        84311 :   decl = nreverse (saved_function_decls);
    8340       460468 :   while (decl)
    8341              :     {
    8342       291846 :       tree next;
    8343              : 
    8344       291846 :       next = DECL_CHAIN (decl);
    8345       291846 :       DECL_CHAIN (decl) = NULL_TREE;
    8346       291846 :       pushdecl (decl);
    8347       291846 :       decl = next;
    8348              :     }
    8349        84311 :   saved_function_decls = NULL_TREE;
    8350              : 
    8351        84311 :   gfc_add_expr_to_block (&outer_block, gfc_finish_wrapped_block (&try_block));
    8352        84311 :   DECL_SAVED_TREE (fndecl) = gfc_finish_block (&outer_block);
    8353        84311 :   decl = getdecls ();
    8354              : 
    8355              :   /* Finish off this function and send it for code generation.  */
    8356        84311 :   poplevel (1, 1);
    8357        84311 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
    8358              : 
    8359       168622 :   DECL_SAVED_TREE (fndecl)
    8360       168622 :     = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
    8361       168622 :                        decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
    8362              : 
    8363              :   /* Output the GENERIC tree.  */
    8364        84311 :   dump_function (TDI_original, fndecl);
    8365              : 
    8366              :   /* Store the end of the function, so that we get good line number
    8367              :      info for the epilogue.  */
    8368        84311 :   cfun->function_end_locus = input_location;
    8369              : 
    8370              :   /* We're leaving the context of this function, so zap cfun.
    8371              :      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
    8372              :      tree_rest_of_compilation.  */
    8373        84311 :   set_cfun (NULL);
    8374              : 
    8375        84311 :   if (old_context)
    8376              :     {
    8377        22902 :       pop_function_context ();
    8378        22902 :       saved_function_decls = saved_parent_function_decls;
    8379              :     }
    8380        84311 :   current_function_decl = old_context;
    8381              : 
    8382        84311 :   if (decl_function_context (fndecl))
    8383              :     {
    8384              :       /* Register this function with cgraph just far enough to get it
    8385              :          added to our parent's nested function list.
    8386              :          If there are static coarrays in this function, the nested _caf_init
    8387              :          function has already called cgraph_create_node, which also created
    8388              :          the cgraph node for this function.  */
    8389        22902 :       if (!has_coarray_vars_or_accessors || flag_coarray != GFC_FCOARRAY_LIB)
    8390        22700 :         (void) cgraph_node::get_create (fndecl);
    8391              :     }
    8392              :   else
    8393        61409 :     cgraph_node::finalize_function (fndecl, true);
    8394              : 
    8395        84311 :   gfc_trans_use_stmts (ns);
    8396        84311 :   gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
    8397              : 
    8398        84311 :   if (sym->attr.is_main_program)
    8399        26085 :     create_main_function (fndecl);
    8400              : 
    8401        84311 :   current_procedure_symbol = previous_procedure_symbol;
    8402        84311 : }
    8403              : 
    8404              : 
    8405              : void
    8406        31350 : gfc_generate_constructors (void)
    8407              : {
    8408        31350 :   gcc_assert (gfc_static_ctors == NULL_TREE);
    8409              : #if 0
    8410              :   tree fnname;
    8411              :   tree type;
    8412              :   tree fndecl;
    8413              :   tree decl;
    8414              :   tree tmp;
    8415              : 
    8416              :   if (gfc_static_ctors == NULL_TREE)
    8417              :     return;
    8418              : 
    8419              :   fnname = get_file_function_name ("I");
    8420              :   type = build_function_type_list (void_type_node, NULL_TREE);
    8421              : 
    8422              :   fndecl = build_decl (input_location,
    8423              :                        FUNCTION_DECL, fnname, type);
    8424              :   TREE_PUBLIC (fndecl) = 1;
    8425              : 
    8426              :   decl = build_decl (input_location,
    8427              :                      RESULT_DECL, NULL_TREE, void_type_node);
    8428              :   DECL_ARTIFICIAL (decl) = 1;
    8429              :   DECL_IGNORED_P (decl) = 1;
    8430              :   DECL_CONTEXT (decl) = fndecl;
    8431              :   DECL_RESULT (fndecl) = decl;
    8432              : 
    8433              :   pushdecl (fndecl);
    8434              : 
    8435              :   current_function_decl = fndecl;
    8436              : 
    8437              :   rest_of_decl_compilation (fndecl, 1, 0);
    8438              : 
    8439              :   make_decl_rtl (fndecl);
    8440              : 
    8441              :   allocate_struct_function (fndecl, false);
    8442              : 
    8443              :   pushlevel ();
    8444              : 
    8445              :   for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
    8446              :     {
    8447              :       tmp = build_call_expr_loc (input_location,
    8448              :                              TREE_VALUE (gfc_static_ctors), 0);
    8449              :       DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
    8450              :     }
    8451              : 
    8452              :   decl = getdecls ();
    8453              :   poplevel (1, 1);
    8454              : 
    8455              :   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
    8456              :   DECL_SAVED_TREE (fndecl)
    8457              :     = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
    8458              :                 DECL_INITIAL (fndecl));
    8459              : 
    8460              :   free_after_parsing (cfun);
    8461              :   free_after_compilation (cfun);
    8462              : 
    8463              :   tree_rest_of_compilation (fndecl);
    8464              : 
    8465              :   current_function_decl = NULL_TREE;
    8466              : #endif
    8467        31350 : }
    8468              : 
    8469              : 
    8470              : /* Helper function for checking of variables declared in a BLOCK DATA program
    8471              :    unit.  */
    8472              : 
    8473              : static void
    8474          300 : check_block_data_decls (gfc_symbol * sym)
    8475              : {
    8476          300 :   if (warn_unused_variable
    8477           13 :       && sym->attr.flavor == FL_VARIABLE
    8478            7 :       && !sym->attr.in_common
    8479            3 :       && !sym->attr.artificial)
    8480              :     {
    8481            2 :       gfc_warning (OPT_Wunused_variable,
    8482              :                    "Symbol %qs at %L is declared in a BLOCK DATA "
    8483              :                    "program unit but is not in a COMMON block",
    8484              :                    sym->name, &sym->declared_at);
    8485              :     }
    8486          300 : }
    8487              : 
    8488              : 
    8489              : /* Translates a BLOCK DATA program unit. This means emitting the
    8490              :    commons contained therein plus their initializations. We also emit
    8491              :    a globally visible symbol to make sure that each BLOCK DATA program
    8492              :    unit remains unique.  */
    8493              : 
    8494              : void
    8495           72 : gfc_generate_block_data (gfc_namespace * ns)
    8496              : {
    8497           72 :   tree decl;
    8498           72 :   tree id;
    8499              : 
    8500              :   /* Tell the backend the source location of the block data.  */
    8501           72 :   if (ns->proc_name)
    8502           29 :     input_location = gfc_get_location (&ns->proc_name->declared_at);
    8503              :   else
    8504           43 :     input_location = gfc_get_location (&gfc_current_locus);
    8505              : 
    8506              :   /* Process the DATA statements.  */
    8507           72 :   gfc_trans_common (ns);
    8508              : 
    8509              :   /* Check for variables declared in BLOCK DATA but not used in COMMON.  */
    8510           72 :   gfc_traverse_ns (ns, check_block_data_decls);
    8511              : 
    8512              :   /* Create a global symbol with the mane of the block data.  This is to
    8513              :      generate linker errors if the same name is used twice.  It is never
    8514              :      really used.  */
    8515           72 :   if (ns->proc_name)
    8516           29 :     id = gfc_sym_mangled_function_id (ns->proc_name);
    8517              :   else
    8518           43 :     id = get_identifier ("__BLOCK_DATA__");
    8519              : 
    8520           72 :   decl = build_decl (input_location,
    8521              :                      VAR_DECL, id, gfc_array_index_type);
    8522           72 :   TREE_PUBLIC (decl) = 1;
    8523           72 :   TREE_STATIC (decl) = 1;
    8524           72 :   DECL_IGNORED_P (decl) = 1;
    8525              : 
    8526           72 :   pushdecl (decl);
    8527           72 :   rest_of_decl_compilation (decl, 1, 0);
    8528           72 : }
    8529              : 
    8530              : void
    8531        13939 : gfc_start_saved_local_decls ()
    8532              : {
    8533        13939 :   gcc_checking_assert (current_function_decl != NULL_TREE);
    8534        13939 :   saved_local_decls = NULL_TREE;
    8535        13939 : }
    8536              : 
    8537              : void
    8538        13939 : gfc_stop_saved_local_decls ()
    8539              : {
    8540        13939 :   tree decl = nreverse (saved_local_decls);
    8541        40793 :   while (decl)
    8542              :     {
    8543        12915 :       tree next;
    8544              : 
    8545        12915 :       next = DECL_CHAIN (decl);
    8546        12915 :       DECL_CHAIN (decl) = NULL_TREE;
    8547        12915 :       pushdecl (decl);
    8548        12915 :       decl = next;
    8549              :     }
    8550        13939 :   saved_local_decls = NULL_TREE;
    8551        13939 : }
    8552              : 
    8553              : /* Process the local variables of a BLOCK construct.  */
    8554              : 
    8555              : void
    8556        13891 : gfc_process_block_locals (gfc_namespace* ns)
    8557              : {
    8558        13891 :   gfc_start_saved_local_decls ();
    8559        13891 :   has_coarray_vars_or_accessors = caf_accessor_head != NULL;
    8560              : 
    8561        13891 :   generate_local_vars (ns);
    8562              : 
    8563        13891 :   if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars_or_accessors)
    8564           41 :     generate_coarray_init (ns);
    8565        13891 :   gfc_stop_saved_local_decls ();
    8566        13891 : }
    8567              : 
    8568              : 
    8569              : #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.