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

Generated by: LCOV version 2.4-beta

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