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

Generated by: LCOV version 2.5.0-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.