Home | History | Annotate | Line # | Download | only in fortran
      1  1.1  mrg /* Code translation -- generate GCC trees from gfc_code.
      2  1.1  mrg    Copyright (C) 2002-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Paul Brook
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg the terms of the GNU General Public License as published by the Free
      9  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     10  1.1  mrg version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1  mrg for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "options.h"
     25  1.1  mrg #include "tree.h"
     26  1.1  mrg #include "gfortran.h"
     27  1.1  mrg #include "gimple-expr.h"	/* For create_tmp_var_raw.  */
     28  1.1  mrg #include "trans.h"
     29  1.1  mrg #include "stringpool.h"
     30  1.1  mrg #include "fold-const.h"
     31  1.1  mrg #include "tree-iterator.h"
     32  1.1  mrg #include "trans-stmt.h"
     33  1.1  mrg #include "trans-array.h"
     34  1.1  mrg #include "trans-types.h"
     35  1.1  mrg #include "trans-const.h"
     36  1.1  mrg 
     37  1.1  mrg /* Naming convention for backend interface code:
     38  1.1  mrg 
     39  1.1  mrg    gfc_trans_*	translate gfc_code into STMT trees.
     40  1.1  mrg 
     41  1.1  mrg    gfc_conv_*	expression conversion
     42  1.1  mrg 
     43  1.1  mrg    gfc_get_*	get a backend tree representation of a decl or type  */
     44  1.1  mrg 
     45  1.1  mrg static gfc_file *gfc_current_backend_file;
     46  1.1  mrg 
     47  1.1  mrg const char gfc_msg_fault[] = N_("Array reference out of bounds");
     48  1.1  mrg 
     49  1.1  mrg 
     50  1.1  mrg /* Return a location_t suitable for 'tree' for a gfortran locus.  The way the
     51  1.1  mrg    parser works in gfortran, loc->lb->location contains only the line number
     52  1.1  mrg    and LOCATION_COLUMN is 0; hence, the column has to be added when generating
     53  1.1  mrg    locations for 'tree'.  Cf. error.cc's gfc_format_decoder.  */
     54  1.1  mrg 
     55  1.1  mrg location_t
     56  1.1  mrg gfc_get_location (locus *loc)
     57  1.1  mrg {
     58  1.1  mrg   return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
     59  1.1  mrg 					      loc->nextc - loc->lb->line);
     60  1.1  mrg }
     61  1.1  mrg 
     62  1.1  mrg /* Advance along TREE_CHAIN n times.  */
     63  1.1  mrg 
     64  1.1  mrg tree
     65  1.1  mrg gfc_advance_chain (tree t, int n)
     66  1.1  mrg {
     67  1.1  mrg   for (; n > 0; n--)
     68  1.1  mrg     {
     69  1.1  mrg       gcc_assert (t != NULL_TREE);
     70  1.1  mrg       t = DECL_CHAIN (t);
     71  1.1  mrg     }
     72  1.1  mrg   return t;
     73  1.1  mrg }
     74  1.1  mrg 
     75  1.1  mrg static int num_var;
     76  1.1  mrg 
     77  1.1  mrg #define MAX_PREFIX_LEN 20
     78  1.1  mrg 
     79  1.1  mrg static tree
     80  1.1  mrg create_var_debug_raw (tree type, const char *prefix)
     81  1.1  mrg {
     82  1.1  mrg   /* Space for prefix + "_" + 10-digit-number + \0.  */
     83  1.1  mrg   char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
     84  1.1  mrg   tree t;
     85  1.1  mrg   int i;
     86  1.1  mrg 
     87  1.1  mrg   if (prefix == NULL)
     88  1.1  mrg     prefix = "gfc";
     89  1.1  mrg   else
     90  1.1  mrg     gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
     91  1.1  mrg 
     92  1.1  mrg   for (i = 0; prefix[i] != 0; i++)
     93  1.1  mrg     name_buf[i] = gfc_wide_toupper (prefix[i]);
     94  1.1  mrg 
     95  1.1  mrg   snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
     96  1.1  mrg 
     97  1.1  mrg   t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
     98  1.1  mrg 
     99  1.1  mrg   /* Not setting this causes some regressions.  */
    100  1.1  mrg   DECL_ARTIFICIAL (t) = 1;
    101  1.1  mrg 
    102  1.1  mrg   /* We want debug info for it.  */
    103  1.1  mrg   DECL_IGNORED_P (t) = 0;
    104  1.1  mrg   /* It should not be nameless.  */
    105  1.1  mrg   DECL_NAMELESS (t) = 0;
    106  1.1  mrg 
    107  1.1  mrg   /* Make the variable writable.  */
    108  1.1  mrg   TREE_READONLY (t) = 0;
    109  1.1  mrg 
    110  1.1  mrg   DECL_EXTERNAL (t) = 0;
    111  1.1  mrg   TREE_STATIC (t) = 0;
    112  1.1  mrg   TREE_USED (t) = 1;
    113  1.1  mrg 
    114  1.1  mrg   return t;
    115  1.1  mrg }
    116  1.1  mrg 
    117  1.1  mrg /* Creates a variable declaration with a given TYPE.  */
    118  1.1  mrg 
    119  1.1  mrg tree
    120  1.1  mrg gfc_create_var_np (tree type, const char *prefix)
    121  1.1  mrg {
    122  1.1  mrg   tree t;
    123  1.1  mrg 
    124  1.1  mrg   if (flag_debug_aux_vars)
    125  1.1  mrg     return create_var_debug_raw (type, prefix);
    126  1.1  mrg 
    127  1.1  mrg   t = create_tmp_var_raw (type, prefix);
    128  1.1  mrg 
    129  1.1  mrg   /* No warnings for anonymous variables.  */
    130  1.1  mrg   if (prefix == NULL)
    131  1.1  mrg     suppress_warning (t);
    132  1.1  mrg 
    133  1.1  mrg   return t;
    134  1.1  mrg }
    135  1.1  mrg 
    136  1.1  mrg 
    137  1.1  mrg /* Like above, but also adds it to the current scope.  */
    138  1.1  mrg 
    139  1.1  mrg tree
    140  1.1  mrg gfc_create_var (tree type, const char *prefix)
    141  1.1  mrg {
    142  1.1  mrg   tree tmp;
    143  1.1  mrg 
    144  1.1  mrg   tmp = gfc_create_var_np (type, prefix);
    145  1.1  mrg 
    146  1.1  mrg   pushdecl (tmp);
    147  1.1  mrg 
    148  1.1  mrg   return tmp;
    149  1.1  mrg }
    150  1.1  mrg 
    151  1.1  mrg 
    152  1.1  mrg /* If the expression is not constant, evaluate it now.  We assign the
    153  1.1  mrg    result of the expression to an artificially created variable VAR, and
    154  1.1  mrg    return a pointer to the VAR_DECL node for this variable.  */
    155  1.1  mrg 
    156  1.1  mrg tree
    157  1.1  mrg gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
    158  1.1  mrg {
    159  1.1  mrg   tree var;
    160  1.1  mrg 
    161  1.1  mrg   if (CONSTANT_CLASS_P (expr))
    162  1.1  mrg     return expr;
    163  1.1  mrg 
    164  1.1  mrg   var = gfc_create_var (TREE_TYPE (expr), NULL);
    165  1.1  mrg   gfc_add_modify_loc (loc, pblock, var, expr);
    166  1.1  mrg 
    167  1.1  mrg   return var;
    168  1.1  mrg }
    169  1.1  mrg 
    170  1.1  mrg 
    171  1.1  mrg tree
    172  1.1  mrg gfc_evaluate_now (tree expr, stmtblock_t * pblock)
    173  1.1  mrg {
    174  1.1  mrg   return gfc_evaluate_now_loc (input_location, expr, pblock);
    175  1.1  mrg }
    176  1.1  mrg 
    177  1.1  mrg /* Like gfc_evaluate_now, but add the created variable to the
    178  1.1  mrg    function scope.  */
    179  1.1  mrg 
    180  1.1  mrg tree
    181  1.1  mrg gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
    182  1.1  mrg {
    183  1.1  mrg   tree var;
    184  1.1  mrg   var = gfc_create_var_np (TREE_TYPE (expr), NULL);
    185  1.1  mrg   gfc_add_decl_to_function (var);
    186  1.1  mrg   gfc_add_modify (pblock, var, expr);
    187  1.1  mrg 
    188  1.1  mrg   return var;
    189  1.1  mrg }
    190  1.1  mrg 
    191  1.1  mrg /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
    192  1.1  mrg    A MODIFY_EXPR is an assignment:
    193  1.1  mrg    LHS <- RHS.  */
    194  1.1  mrg 
    195  1.1  mrg void
    196  1.1  mrg gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
    197  1.1  mrg {
    198  1.1  mrg   tree tmp;
    199  1.1  mrg 
    200  1.1  mrg   tree t1, t2;
    201  1.1  mrg   t1 = TREE_TYPE (rhs);
    202  1.1  mrg   t2 = TREE_TYPE (lhs);
    203  1.1  mrg   /* Make sure that the types of the rhs and the lhs are compatible
    204  1.1  mrg      for scalar assignments.  We should probably have something
    205  1.1  mrg      similar for aggregates, but right now removing that check just
    206  1.1  mrg      breaks everything.  */
    207  1.1  mrg   gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
    208  1.1  mrg 		       || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
    209  1.1  mrg 
    210  1.1  mrg   tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
    211  1.1  mrg 			 rhs);
    212  1.1  mrg   gfc_add_expr_to_block (pblock, tmp);
    213  1.1  mrg }
    214  1.1  mrg 
    215  1.1  mrg 
    216  1.1  mrg void
    217  1.1  mrg gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
    218  1.1  mrg {
    219  1.1  mrg   gfc_add_modify_loc (input_location, pblock, lhs, rhs);
    220  1.1  mrg }
    221  1.1  mrg 
    222  1.1  mrg 
    223  1.1  mrg /* Create a new scope/binding level and initialize a block.  Care must be
    224  1.1  mrg    taken when translating expressions as any temporaries will be placed in
    225  1.1  mrg    the innermost scope.  */
    226  1.1  mrg 
    227  1.1  mrg void
    228  1.1  mrg gfc_start_block (stmtblock_t * block)
    229  1.1  mrg {
    230  1.1  mrg   /* Start a new binding level.  */
    231  1.1  mrg   pushlevel ();
    232  1.1  mrg   block->has_scope = 1;
    233  1.1  mrg 
    234  1.1  mrg   /* The block is empty.  */
    235  1.1  mrg   block->head = NULL_TREE;
    236  1.1  mrg }
    237  1.1  mrg 
    238  1.1  mrg 
    239  1.1  mrg /* Initialize a block without creating a new scope.  */
    240  1.1  mrg 
    241  1.1  mrg void
    242  1.1  mrg gfc_init_block (stmtblock_t * block)
    243  1.1  mrg {
    244  1.1  mrg   block->head = NULL_TREE;
    245  1.1  mrg   block->has_scope = 0;
    246  1.1  mrg }
    247  1.1  mrg 
    248  1.1  mrg 
    249  1.1  mrg /* Sometimes we create a scope but it turns out that we don't actually
    250  1.1  mrg    need it.  This function merges the scope of BLOCK with its parent.
    251  1.1  mrg    Only variable decls will be merged, you still need to add the code.  */
    252  1.1  mrg 
    253  1.1  mrg void
    254  1.1  mrg gfc_merge_block_scope (stmtblock_t * block)
    255  1.1  mrg {
    256  1.1  mrg   tree decl;
    257  1.1  mrg   tree next;
    258  1.1  mrg 
    259  1.1  mrg   gcc_assert (block->has_scope);
    260  1.1  mrg   block->has_scope = 0;
    261  1.1  mrg 
    262  1.1  mrg   /* Remember the decls in this scope.  */
    263  1.1  mrg   decl = getdecls ();
    264  1.1  mrg   poplevel (0, 0);
    265  1.1  mrg 
    266  1.1  mrg   /* Add them to the parent scope.  */
    267  1.1  mrg   while (decl != NULL_TREE)
    268  1.1  mrg     {
    269  1.1  mrg       next = DECL_CHAIN (decl);
    270  1.1  mrg       DECL_CHAIN (decl) = NULL_TREE;
    271  1.1  mrg 
    272  1.1  mrg       pushdecl (decl);
    273  1.1  mrg       decl = next;
    274  1.1  mrg     }
    275  1.1  mrg }
    276  1.1  mrg 
    277  1.1  mrg 
    278  1.1  mrg /* Finish a scope containing a block of statements.  */
    279  1.1  mrg 
    280  1.1  mrg tree
    281  1.1  mrg gfc_finish_block (stmtblock_t * stmtblock)
    282  1.1  mrg {
    283  1.1  mrg   tree decl;
    284  1.1  mrg   tree expr;
    285  1.1  mrg   tree block;
    286  1.1  mrg 
    287  1.1  mrg   expr = stmtblock->head;
    288  1.1  mrg   if (!expr)
    289  1.1  mrg     expr = build_empty_stmt (input_location);
    290  1.1  mrg 
    291  1.1  mrg   stmtblock->head = NULL_TREE;
    292  1.1  mrg 
    293  1.1  mrg   if (stmtblock->has_scope)
    294  1.1  mrg     {
    295  1.1  mrg       decl = getdecls ();
    296  1.1  mrg 
    297  1.1  mrg       if (decl)
    298  1.1  mrg 	{
    299  1.1  mrg 	  block = poplevel (1, 0);
    300  1.1  mrg 	  expr = build3_v (BIND_EXPR, decl, expr, block);
    301  1.1  mrg 	}
    302  1.1  mrg       else
    303  1.1  mrg 	poplevel (0, 0);
    304  1.1  mrg     }
    305  1.1  mrg 
    306  1.1  mrg   return expr;
    307  1.1  mrg }
    308  1.1  mrg 
    309  1.1  mrg 
    310  1.1  mrg /* Build an ADDR_EXPR and cast the result to TYPE.  If TYPE is NULL, the
    311  1.1  mrg    natural type is used.  */
    312  1.1  mrg 
    313  1.1  mrg tree
    314  1.1  mrg gfc_build_addr_expr (tree type, tree t)
    315  1.1  mrg {
    316  1.1  mrg   tree base_type = TREE_TYPE (t);
    317  1.1  mrg   tree natural_type;
    318  1.1  mrg 
    319  1.1  mrg   if (type && POINTER_TYPE_P (type)
    320  1.1  mrg       && TREE_CODE (base_type) == ARRAY_TYPE
    321  1.1  mrg       && TYPE_MAIN_VARIANT (TREE_TYPE (type))
    322  1.1  mrg 	 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
    323  1.1  mrg     {
    324  1.1  mrg       tree min_val = size_zero_node;
    325  1.1  mrg       tree type_domain = TYPE_DOMAIN (base_type);
    326  1.1  mrg       if (type_domain && TYPE_MIN_VALUE (type_domain))
    327  1.1  mrg         min_val = TYPE_MIN_VALUE (type_domain);
    328  1.1  mrg       t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
    329  1.1  mrg 			    t, min_val, NULL_TREE, NULL_TREE));
    330  1.1  mrg       natural_type = type;
    331  1.1  mrg     }
    332  1.1  mrg   else
    333  1.1  mrg     natural_type = build_pointer_type (base_type);
    334  1.1  mrg 
    335  1.1  mrg   if (TREE_CODE (t) == INDIRECT_REF)
    336  1.1  mrg     {
    337  1.1  mrg       if (!type)
    338  1.1  mrg 	type = natural_type;
    339  1.1  mrg       t = TREE_OPERAND (t, 0);
    340  1.1  mrg       natural_type = TREE_TYPE (t);
    341  1.1  mrg     }
    342  1.1  mrg   else
    343  1.1  mrg     {
    344  1.1  mrg       tree base = get_base_address (t);
    345  1.1  mrg       if (base && DECL_P (base))
    346  1.1  mrg         TREE_ADDRESSABLE (base) = 1;
    347  1.1  mrg       t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
    348  1.1  mrg     }
    349  1.1  mrg 
    350  1.1  mrg   if (type && natural_type != type)
    351  1.1  mrg     t = convert (type, t);
    352  1.1  mrg 
    353  1.1  mrg   return t;
    354  1.1  mrg }
    355  1.1  mrg 
    356  1.1  mrg 
    357  1.1  mrg static tree
    358  1.1  mrg get_array_span (tree type, tree decl)
    359  1.1  mrg {
    360  1.1  mrg   tree span;
    361  1.1  mrg 
    362  1.1  mrg   /* Component references are guaranteed to have a reliable value for
    363  1.1  mrg      'span'. Likewise indirect references since they emerge from the
    364  1.1  mrg      conversion of a CFI descriptor or the hidden dummy descriptor.  */
    365  1.1  mrg   if (TREE_CODE (decl) == COMPONENT_REF
    366  1.1  mrg       && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
    367  1.1  mrg     return gfc_conv_descriptor_span_get (decl);
    368  1.1  mrg   else if (TREE_CODE (decl) == INDIRECT_REF
    369  1.1  mrg 	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
    370  1.1  mrg     return gfc_conv_descriptor_span_get (decl);
    371  1.1  mrg 
    372  1.1  mrg   /* Return the span for deferred character length array references.  */
    373  1.1  mrg   if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
    374  1.1  mrg     {
    375  1.1  mrg       if (TREE_CODE (decl) == PARM_DECL)
    376  1.1  mrg 	decl = build_fold_indirect_ref_loc (input_location, decl);
    377  1.1  mrg       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
    378  1.1  mrg 	span = gfc_conv_descriptor_span_get (decl);
    379  1.1  mrg       else
    380  1.1  mrg 	span = gfc_get_character_len_in_bytes (type);
    381  1.1  mrg       span = (span && !integer_zerop (span))
    382  1.1  mrg 	? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE);
    383  1.1  mrg     }
    384  1.1  mrg   /* Likewise for class array or pointer array references.  */
    385  1.1  mrg   else if (TREE_CODE (decl) == FIELD_DECL
    386  1.1  mrg 	   || VAR_OR_FUNCTION_DECL_P (decl)
    387  1.1  mrg 	   || TREE_CODE (decl) == PARM_DECL)
    388  1.1  mrg     {
    389  1.1  mrg       if (GFC_DECL_CLASS (decl))
    390  1.1  mrg 	{
    391  1.1  mrg 	  /* When a temporary is in place for the class array, then the
    392  1.1  mrg 	     original class' declaration is stored in the saved
    393  1.1  mrg 	     descriptor.  */
    394  1.1  mrg 	  if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
    395  1.1  mrg 	    decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
    396  1.1  mrg 	  else
    397  1.1  mrg 	    {
    398  1.1  mrg 	      /* Allow for dummy arguments and other good things.  */
    399  1.1  mrg 	      if (POINTER_TYPE_P (TREE_TYPE (decl)))
    400  1.1  mrg 		decl = build_fold_indirect_ref_loc (input_location, decl);
    401  1.1  mrg 
    402  1.1  mrg 	      /* Check if '_data' is an array descriptor.  If it is not,
    403  1.1  mrg 		 the array must be one of the components of the class
    404  1.1  mrg 		 object, so return a null span.  */
    405  1.1  mrg 	      if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
    406  1.1  mrg 					  gfc_class_data_get (decl))))
    407  1.1  mrg 		return NULL_TREE;
    408  1.1  mrg 	    }
    409  1.1  mrg 	  span = gfc_class_vtab_size_get (decl);
    410  1.1  mrg 	  /* For unlimited polymorphic entities then _len component needs
    411  1.1  mrg 	     to be multiplied with the size.  */
    412  1.1  mrg 	  span = gfc_resize_class_size_with_len (NULL, decl, span);
    413  1.1  mrg 	}
    414  1.1  mrg       else if (GFC_DECL_PTR_ARRAY_P (decl))
    415  1.1  mrg 	{
    416  1.1  mrg 	  if (TREE_CODE (decl) == PARM_DECL)
    417  1.1  mrg 	    decl = build_fold_indirect_ref_loc (input_location, decl);
    418  1.1  mrg 	  span = gfc_conv_descriptor_span_get (decl);
    419  1.1  mrg 	}
    420  1.1  mrg       else
    421  1.1  mrg 	span = NULL_TREE;
    422  1.1  mrg     }
    423  1.1  mrg   else
    424  1.1  mrg     span = NULL_TREE;
    425  1.1  mrg 
    426  1.1  mrg   return span;
    427  1.1  mrg }
    428  1.1  mrg 
    429  1.1  mrg 
    430  1.1  mrg tree
    431  1.1  mrg gfc_build_spanned_array_ref (tree base, tree offset, tree span)
    432  1.1  mrg {
    433  1.1  mrg   tree type;
    434  1.1  mrg   tree tmp;
    435  1.1  mrg   type = TREE_TYPE (TREE_TYPE (base));
    436  1.1  mrg   offset = fold_build2_loc (input_location, MULT_EXPR,
    437  1.1  mrg 			    gfc_array_index_type,
    438  1.1  mrg 			    offset, span);
    439  1.1  mrg   tmp = gfc_build_addr_expr (pvoid_type_node, base);
    440  1.1  mrg   tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
    441  1.1  mrg   tmp = fold_convert (build_pointer_type (type), tmp);
    442  1.1  mrg   if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
    443  1.1  mrg       || !TYPE_STRING_FLAG (type))
    444  1.1  mrg     tmp = build_fold_indirect_ref_loc (input_location, tmp);
    445  1.1  mrg   return tmp;
    446  1.1  mrg }
    447  1.1  mrg 
    448  1.1  mrg 
    449  1.1  mrg /* Build an ARRAY_REF with its natural type.
    450  1.1  mrg    NON_NEGATIVE_OFFSET indicates if its true that OFFSET cant be negative,
    451  1.1  mrg    and thus that an ARRAY_REF can safely be generated.  If its false, we
    452  1.1  mrg    have to play it safe and use pointer arithmetic.  */
    453  1.1  mrg 
    454  1.1  mrg tree
    455  1.1  mrg gfc_build_array_ref (tree base, tree offset, tree decl,
    456  1.1  mrg 		     bool non_negative_offset, tree vptr)
    457  1.1  mrg {
    458  1.1  mrg   tree type = TREE_TYPE (base);
    459  1.1  mrg   tree span = NULL_TREE;
    460  1.1  mrg 
    461  1.1  mrg   if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
    462  1.1  mrg     {
    463  1.1  mrg       gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
    464  1.1  mrg 
    465  1.1  mrg       return fold_convert (TYPE_MAIN_VARIANT (type), base);
    466  1.1  mrg     }
    467  1.1  mrg 
    468  1.1  mrg   /* Scalar coarray, there is nothing to do.  */
    469  1.1  mrg   if (TREE_CODE (type) != ARRAY_TYPE)
    470  1.1  mrg     {
    471  1.1  mrg       gcc_assert (decl == NULL_TREE);
    472  1.1  mrg       gcc_assert (integer_zerop (offset));
    473  1.1  mrg       return base;
    474  1.1  mrg     }
    475  1.1  mrg 
    476  1.1  mrg   type = TREE_TYPE (type);
    477  1.1  mrg 
    478  1.1  mrg   if (DECL_P (base))
    479  1.1  mrg     TREE_ADDRESSABLE (base) = 1;
    480  1.1  mrg 
    481  1.1  mrg   /* Strip NON_LVALUE_EXPR nodes.  */
    482  1.1  mrg   STRIP_TYPE_NOPS (offset);
    483  1.1  mrg 
    484  1.1  mrg   /* If decl or vptr are non-null, pointer arithmetic for the array reference
    485  1.1  mrg      is likely. Generate the 'span' for the array reference.  */
    486  1.1  mrg   if (vptr)
    487  1.1  mrg     {
    488  1.1  mrg       span = gfc_vptr_size_get (vptr);
    489  1.1  mrg 
    490  1.1  mrg       /* Check if this is an unlimited polymorphic object carrying a character
    491  1.1  mrg 	 payload. In this case, the 'len' field is non-zero.  */
    492  1.1  mrg       if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
    493  1.1  mrg 	span = gfc_resize_class_size_with_len (NULL, decl, span);
    494  1.1  mrg     }
    495  1.1  mrg   else if (decl)
    496  1.1  mrg     span = get_array_span (type, decl);
    497  1.1  mrg 
    498  1.1  mrg   /* If a non-null span has been generated reference the element with
    499  1.1  mrg      pointer arithmetic.  */
    500  1.1  mrg   if (span != NULL_TREE)
    501  1.1  mrg     return gfc_build_spanned_array_ref (base, offset, span);
    502  1.1  mrg   /* Else use a straightforward array reference if possible.  */
    503  1.1  mrg   else if (non_negative_offset)
    504  1.1  mrg     return build4_loc (input_location, ARRAY_REF, type, base, offset,
    505  1.1  mrg 		       NULL_TREE, NULL_TREE);
    506  1.1  mrg   /* Otherwise use pointer arithmetic.  */
    507  1.1  mrg   else
    508  1.1  mrg     {
    509  1.1  mrg       gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
    510  1.1  mrg       tree min = NULL_TREE;
    511  1.1  mrg       if (TYPE_DOMAIN (TREE_TYPE (base))
    512  1.1  mrg 	  && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
    513  1.1  mrg 	min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
    514  1.1  mrg 
    515  1.1  mrg       tree zero_based_index
    516  1.1  mrg 	   = min ? fold_build2_loc (input_location, MINUS_EXPR,
    517  1.1  mrg 				    gfc_array_index_type,
    518  1.1  mrg 				    fold_convert (gfc_array_index_type, offset),
    519  1.1  mrg 				    fold_convert (gfc_array_index_type, min))
    520  1.1  mrg 		 : fold_convert (gfc_array_index_type, offset);
    521  1.1  mrg 
    522  1.1  mrg       tree elt_size = fold_convert (gfc_array_index_type,
    523  1.1  mrg 				    TYPE_SIZE_UNIT (type));
    524  1.1  mrg 
    525  1.1  mrg       tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
    526  1.1  mrg 					   gfc_array_index_type,
    527  1.1  mrg 					   zero_based_index, elt_size);
    528  1.1  mrg 
    529  1.1  mrg       tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
    530  1.1  mrg 
    531  1.1  mrg       tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
    532  1.1  mrg 					      offset_bytes);
    533  1.1  mrg       return build1_loc (input_location, INDIRECT_REF, type,
    534  1.1  mrg 			 fold_convert (build_pointer_type (type), ptr));
    535  1.1  mrg     }
    536  1.1  mrg }
    537  1.1  mrg 
    538  1.1  mrg 
    539  1.1  mrg /* Generate a call to print a runtime error possibly including multiple
    540  1.1  mrg    arguments and a locus.  */
    541  1.1  mrg 
    542  1.1  mrg static tree
    543  1.1  mrg trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
    544  1.1  mrg 			    va_list ap)
    545  1.1  mrg {
    546  1.1  mrg   stmtblock_t block;
    547  1.1  mrg   tree tmp;
    548  1.1  mrg   tree arg, arg2;
    549  1.1  mrg   tree *argarray;
    550  1.1  mrg   tree fntype;
    551  1.1  mrg   char *message;
    552  1.1  mrg   const char *p;
    553  1.1  mrg   int line, nargs, i;
    554  1.1  mrg   location_t loc;
    555  1.1  mrg 
    556  1.1  mrg   /* Compute the number of extra arguments from the format string.  */
    557  1.1  mrg   for (p = msgid, nargs = 0; *p; p++)
    558  1.1  mrg     if (*p == '%')
    559  1.1  mrg       {
    560  1.1  mrg 	p++;
    561  1.1  mrg 	if (*p != '%')
    562  1.1  mrg 	  nargs++;
    563  1.1  mrg       }
    564  1.1  mrg 
    565  1.1  mrg   /* The code to generate the error.  */
    566  1.1  mrg   gfc_start_block (&block);
    567  1.1  mrg 
    568  1.1  mrg   if (where)
    569  1.1  mrg     {
    570  1.1  mrg       line = LOCATION_LINE (where->lb->location);
    571  1.1  mrg       message = xasprintf ("At line %d of file %s",  line,
    572  1.1  mrg 			   where->lb->file->filename);
    573  1.1  mrg     }
    574  1.1  mrg   else
    575  1.1  mrg     message = xasprintf ("In file '%s', around line %d",
    576  1.1  mrg 			 gfc_source_file, LOCATION_LINE (input_location) + 1);
    577  1.1  mrg 
    578  1.1  mrg   arg = gfc_build_addr_expr (pchar_type_node,
    579  1.1  mrg 			     gfc_build_localized_cstring_const (message));
    580  1.1  mrg   free (message);
    581  1.1  mrg 
    582  1.1  mrg   message = xasprintf ("%s", _(msgid));
    583  1.1  mrg   arg2 = gfc_build_addr_expr (pchar_type_node,
    584  1.1  mrg 			      gfc_build_localized_cstring_const (message));
    585  1.1  mrg   free (message);
    586  1.1  mrg 
    587  1.1  mrg   /* Build the argument array.  */
    588  1.1  mrg   argarray = XALLOCAVEC (tree, nargs + 2);
    589  1.1  mrg   argarray[0] = arg;
    590  1.1  mrg   argarray[1] = arg2;
    591  1.1  mrg   for (i = 0; i < nargs; i++)
    592  1.1  mrg     argarray[2 + i] = va_arg (ap, tree);
    593  1.1  mrg 
    594  1.1  mrg   /* Build the function call to runtime_(warning,error)_at; because of the
    595  1.1  mrg      variable number of arguments, we can't use build_call_expr_loc dinput_location,
    596  1.1  mrg      irectly.  */
    597  1.1  mrg   fntype = TREE_TYPE (errorfunc);
    598  1.1  mrg 
    599  1.1  mrg   loc = where ? gfc_get_location (where) : input_location;
    600  1.1  mrg   tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
    601  1.1  mrg 				   fold_build1_loc (loc, ADDR_EXPR,
    602  1.1  mrg 					     build_pointer_type (fntype),
    603  1.1  mrg 					     errorfunc),
    604  1.1  mrg 				   nargs + 2, argarray);
    605  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
    606  1.1  mrg 
    607  1.1  mrg   return gfc_finish_block (&block);
    608  1.1  mrg }
    609  1.1  mrg 
    610  1.1  mrg 
    611  1.1  mrg tree
    612  1.1  mrg gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
    613  1.1  mrg {
    614  1.1  mrg   va_list ap;
    615  1.1  mrg   tree result;
    616  1.1  mrg 
    617  1.1  mrg   va_start (ap, msgid);
    618  1.1  mrg   result = trans_runtime_error_vararg (error
    619  1.1  mrg 				       ? gfor_fndecl_runtime_error_at
    620  1.1  mrg 				       : gfor_fndecl_runtime_warning_at,
    621  1.1  mrg 				       where, msgid, ap);
    622  1.1  mrg   va_end (ap);
    623  1.1  mrg   return result;
    624  1.1  mrg }
    625  1.1  mrg 
    626  1.1  mrg 
    627  1.1  mrg /* Generate a runtime error if COND is true.  */
    628  1.1  mrg 
    629  1.1  mrg void
    630  1.1  mrg gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
    631  1.1  mrg 			 locus * where, const char * msgid, ...)
    632  1.1  mrg {
    633  1.1  mrg   va_list ap;
    634  1.1  mrg   stmtblock_t block;
    635  1.1  mrg   tree body;
    636  1.1  mrg   tree tmp;
    637  1.1  mrg   tree tmpvar = NULL;
    638  1.1  mrg 
    639  1.1  mrg   if (integer_zerop (cond))
    640  1.1  mrg     return;
    641  1.1  mrg 
    642  1.1  mrg   if (once)
    643  1.1  mrg     {
    644  1.1  mrg        tmpvar = gfc_create_var (boolean_type_node, "print_warning");
    645  1.1  mrg        TREE_STATIC (tmpvar) = 1;
    646  1.1  mrg        DECL_INITIAL (tmpvar) = boolean_true_node;
    647  1.1  mrg        gfc_add_expr_to_block (pblock, tmpvar);
    648  1.1  mrg     }
    649  1.1  mrg 
    650  1.1  mrg   gfc_start_block (&block);
    651  1.1  mrg 
    652  1.1  mrg   /* For error, runtime_error_at already implies PRED_NORETURN.  */
    653  1.1  mrg   if (!error && once)
    654  1.1  mrg     gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
    655  1.1  mrg 						       NOT_TAKEN));
    656  1.1  mrg 
    657  1.1  mrg   /* The code to generate the error.  */
    658  1.1  mrg   va_start (ap, msgid);
    659  1.1  mrg   gfc_add_expr_to_block (&block,
    660  1.1  mrg 			 trans_runtime_error_vararg
    661  1.1  mrg 			 (error ? gfor_fndecl_runtime_error_at
    662  1.1  mrg 			  : gfor_fndecl_runtime_warning_at,
    663  1.1  mrg 			  where, msgid, ap));
    664  1.1  mrg   va_end (ap);
    665  1.1  mrg 
    666  1.1  mrg   if (once)
    667  1.1  mrg     gfc_add_modify (&block, tmpvar, boolean_false_node);
    668  1.1  mrg 
    669  1.1  mrg   body = gfc_finish_block (&block);
    670  1.1  mrg 
    671  1.1  mrg   if (integer_onep (cond))
    672  1.1  mrg     {
    673  1.1  mrg       gfc_add_expr_to_block (pblock, body);
    674  1.1  mrg     }
    675  1.1  mrg   else
    676  1.1  mrg     {
    677  1.1  mrg       if (once)
    678  1.1  mrg 	cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
    679  1.1  mrg 				boolean_type_node, tmpvar,
    680  1.1  mrg 				fold_convert (boolean_type_node, cond));
    681  1.1  mrg 
    682  1.1  mrg       tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
    683  1.1  mrg 			     cond, body,
    684  1.1  mrg 			     build_empty_stmt (gfc_get_location (where)));
    685  1.1  mrg       gfc_add_expr_to_block (pblock, tmp);
    686  1.1  mrg     }
    687  1.1  mrg }
    688  1.1  mrg 
    689  1.1  mrg 
    690  1.1  mrg static tree
    691  1.1  mrg trans_os_error_at (locus* where, const char* msgid, ...)
    692  1.1  mrg {
    693  1.1  mrg   va_list ap;
    694  1.1  mrg   tree result;
    695  1.1  mrg 
    696  1.1  mrg   va_start (ap, msgid);
    697  1.1  mrg   result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
    698  1.1  mrg 				       where, msgid, ap);
    699  1.1  mrg   va_end (ap);
    700  1.1  mrg   return result;
    701  1.1  mrg }
    702  1.1  mrg 
    703  1.1  mrg 
    704  1.1  mrg 
    705  1.1  mrg /* Call malloc to allocate size bytes of memory, with special conditions:
    706  1.1  mrg       + if size == 0, return a malloced area of size 1,
    707  1.1  mrg       + if malloc returns NULL, issue a runtime error.  */
    708  1.1  mrg tree
    709  1.1  mrg gfc_call_malloc (stmtblock_t * block, tree type, tree size)
    710  1.1  mrg {
    711  1.1  mrg   tree tmp, malloc_result, null_result, res, malloc_tree;
    712  1.1  mrg   stmtblock_t block2;
    713  1.1  mrg 
    714  1.1  mrg   /* Create a variable to hold the result.  */
    715  1.1  mrg   res = gfc_create_var (prvoid_type_node, NULL);
    716  1.1  mrg 
    717  1.1  mrg   /* Call malloc.  */
    718  1.1  mrg   gfc_start_block (&block2);
    719  1.1  mrg 
    720  1.1  mrg   if (size == NULL_TREE)
    721  1.1  mrg     size = build_int_cst (size_type_node, 1);
    722  1.1  mrg 
    723  1.1  mrg   size = fold_convert (size_type_node, size);
    724  1.1  mrg   size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
    725  1.1  mrg 			  build_int_cst (size_type_node, 1));
    726  1.1  mrg 
    727  1.1  mrg   malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
    728  1.1  mrg   gfc_add_modify (&block2, res,
    729  1.1  mrg 		  fold_convert (prvoid_type_node,
    730  1.1  mrg 				build_call_expr_loc (input_location,
    731  1.1  mrg 						     malloc_tree, 1, size)));
    732  1.1  mrg 
    733  1.1  mrg   /* Optionally check whether malloc was successful.  */
    734  1.1  mrg   if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
    735  1.1  mrg     {
    736  1.1  mrg       null_result = fold_build2_loc (input_location, EQ_EXPR,
    737  1.1  mrg 				     logical_type_node, res,
    738  1.1  mrg 				     build_int_cst (pvoid_type_node, 0));
    739  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
    740  1.1  mrg 			     null_result,
    741  1.1  mrg 			     trans_os_error_at (NULL,
    742  1.1  mrg 						"Error allocating %lu bytes",
    743  1.1  mrg 						fold_convert
    744  1.1  mrg 						(long_unsigned_type_node,
    745  1.1  mrg 						 size)),
    746  1.1  mrg 			     build_empty_stmt (input_location));
    747  1.1  mrg       gfc_add_expr_to_block (&block2, tmp);
    748  1.1  mrg     }
    749  1.1  mrg 
    750  1.1  mrg   malloc_result = gfc_finish_block (&block2);
    751  1.1  mrg   gfc_add_expr_to_block (block, malloc_result);
    752  1.1  mrg 
    753  1.1  mrg   if (type != NULL)
    754  1.1  mrg     res = fold_convert (type, res);
    755  1.1  mrg   return res;
    756  1.1  mrg }
    757  1.1  mrg 
    758  1.1  mrg 
    759  1.1  mrg /* Allocate memory, using an optional status argument.
    760  1.1  mrg 
    761  1.1  mrg    This function follows the following pseudo-code:
    762  1.1  mrg 
    763  1.1  mrg     void *
    764  1.1  mrg     allocate (size_t size, integer_type stat)
    765  1.1  mrg     {
    766  1.1  mrg       void *newmem;
    767  1.1  mrg 
    768  1.1  mrg       if (stat requested)
    769  1.1  mrg 	stat = 0;
    770  1.1  mrg 
    771  1.1  mrg       newmem = malloc (MAX (size, 1));
    772  1.1  mrg       if (newmem == NULL)
    773  1.1  mrg       {
    774  1.1  mrg         if (stat)
    775  1.1  mrg           *stat = LIBERROR_ALLOCATION;
    776  1.1  mrg         else
    777  1.1  mrg 	  runtime_error ("Allocation would exceed memory limit");
    778  1.1  mrg       }
    779  1.1  mrg       return newmem;
    780  1.1  mrg     }  */
    781  1.1  mrg void
    782  1.1  mrg gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
    783  1.1  mrg 			   tree size, tree status)
    784  1.1  mrg {
    785  1.1  mrg   tree tmp, error_cond;
    786  1.1  mrg   stmtblock_t on_error;
    787  1.1  mrg   tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
    788  1.1  mrg 
    789  1.1  mrg   /* If successful and stat= is given, set status to 0.  */
    790  1.1  mrg   if (status != NULL_TREE)
    791  1.1  mrg       gfc_add_expr_to_block (block,
    792  1.1  mrg 	     fold_build2_loc (input_location, MODIFY_EXPR, status_type,
    793  1.1  mrg 			      status, build_int_cst (status_type, 0)));
    794  1.1  mrg 
    795  1.1  mrg   /* The allocation itself.  */
    796  1.1  mrg   size = fold_convert (size_type_node, size);
    797  1.1  mrg   gfc_add_modify (block, pointer,
    798  1.1  mrg 	  fold_convert (TREE_TYPE (pointer),
    799  1.1  mrg 		build_call_expr_loc (input_location,
    800  1.1  mrg 			     builtin_decl_explicit (BUILT_IN_MALLOC), 1,
    801  1.1  mrg 			     fold_build2_loc (input_location,
    802  1.1  mrg 				      MAX_EXPR, size_type_node, size,
    803  1.1  mrg 				      build_int_cst (size_type_node, 1)))));
    804  1.1  mrg 
    805  1.1  mrg   /* What to do in case of error.  */
    806  1.1  mrg   gfc_start_block (&on_error);
    807  1.1  mrg   if (status != NULL_TREE)
    808  1.1  mrg     {
    809  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
    810  1.1  mrg 			     build_int_cst (status_type, LIBERROR_ALLOCATION));
    811  1.1  mrg       gfc_add_expr_to_block (&on_error, tmp);
    812  1.1  mrg     }
    813  1.1  mrg   else
    814  1.1  mrg     {
    815  1.1  mrg       /* Here, os_error_at already implies PRED_NORETURN.  */
    816  1.1  mrg       tree lusize = fold_convert (long_unsigned_type_node, size);
    817  1.1  mrg       tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
    818  1.1  mrg       gfc_add_expr_to_block (&on_error, tmp);
    819  1.1  mrg     }
    820  1.1  mrg 
    821  1.1  mrg   error_cond = fold_build2_loc (input_location, EQ_EXPR,
    822  1.1  mrg 				logical_type_node, pointer,
    823  1.1  mrg 				build_int_cst (prvoid_type_node, 0));
    824  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
    825  1.1  mrg 			 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
    826  1.1  mrg 			 gfc_finish_block (&on_error),
    827  1.1  mrg 			 build_empty_stmt (input_location));
    828  1.1  mrg 
    829  1.1  mrg   gfc_add_expr_to_block (block, tmp);
    830  1.1  mrg }
    831  1.1  mrg 
    832  1.1  mrg 
    833  1.1  mrg /* Allocate memory, using an optional status argument.
    834  1.1  mrg 
    835  1.1  mrg    This function follows the following pseudo-code:
    836  1.1  mrg 
    837  1.1  mrg     void *
    838  1.1  mrg     allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
    839  1.1  mrg     {
    840  1.1  mrg       void *newmem;
    841  1.1  mrg 
    842  1.1  mrg       newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
    843  1.1  mrg       return newmem;
    844  1.1  mrg     }  */
    845  1.1  mrg void
    846  1.1  mrg gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
    847  1.1  mrg 			    tree token, tree status, tree errmsg, tree errlen,
    848  1.1  mrg 			    gfc_coarray_regtype alloc_type)
    849  1.1  mrg {
    850  1.1  mrg   tree tmp, pstat;
    851  1.1  mrg 
    852  1.1  mrg   gcc_assert (token != NULL_TREE);
    853  1.1  mrg 
    854  1.1  mrg   /* The allocation itself.  */
    855  1.1  mrg   if (status == NULL_TREE)
    856  1.1  mrg     pstat  = null_pointer_node;
    857  1.1  mrg   else
    858  1.1  mrg     pstat  = gfc_build_addr_expr (NULL_TREE, status);
    859  1.1  mrg 
    860  1.1  mrg   if (errmsg == NULL_TREE)
    861  1.1  mrg     {
    862  1.1  mrg       gcc_assert(errlen == NULL_TREE);
    863  1.1  mrg       errmsg = null_pointer_node;
    864  1.1  mrg       errlen = build_int_cst (integer_type_node, 0);
    865  1.1  mrg     }
    866  1.1  mrg 
    867  1.1  mrg   size = fold_convert (size_type_node, size);
    868  1.1  mrg   tmp = build_call_expr_loc (input_location,
    869  1.1  mrg 	     gfor_fndecl_caf_register, 7,
    870  1.1  mrg 	     fold_build2_loc (input_location,
    871  1.1  mrg 			      MAX_EXPR, size_type_node, size, size_one_node),
    872  1.1  mrg 	     build_int_cst (integer_type_node, alloc_type),
    873  1.1  mrg 	     token, gfc_build_addr_expr (pvoid_type_node, pointer),
    874  1.1  mrg 	     pstat, errmsg, errlen);
    875  1.1  mrg 
    876  1.1  mrg   gfc_add_expr_to_block (block, tmp);
    877  1.1  mrg 
    878  1.1  mrg   /* It guarantees memory consistency within the same segment */
    879  1.1  mrg   tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
    880  1.1  mrg   tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
    881  1.1  mrg 		    gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
    882  1.1  mrg 		    tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
    883  1.1  mrg   ASM_VOLATILE_P (tmp) = 1;
    884  1.1  mrg   gfc_add_expr_to_block (block, tmp);
    885  1.1  mrg }
    886  1.1  mrg 
    887  1.1  mrg 
    888  1.1  mrg /* Generate code for an ALLOCATE statement when the argument is an
    889  1.1  mrg    allocatable variable.  If the variable is currently allocated, it is an
    890  1.1  mrg    error to allocate it again.
    891  1.1  mrg 
    892  1.1  mrg    This function follows the following pseudo-code:
    893  1.1  mrg 
    894  1.1  mrg     void *
    895  1.1  mrg     allocate_allocatable (void *mem, size_t size, integer_type stat)
    896  1.1  mrg     {
    897  1.1  mrg       if (mem == NULL)
    898  1.1  mrg 	return allocate (size, stat);
    899  1.1  mrg       else
    900  1.1  mrg       {
    901  1.1  mrg 	if (stat)
    902  1.1  mrg 	  stat = LIBERROR_ALLOCATION;
    903  1.1  mrg 	else
    904  1.1  mrg 	  runtime_error ("Attempting to allocate already allocated variable");
    905  1.1  mrg       }
    906  1.1  mrg     }
    907  1.1  mrg 
    908  1.1  mrg     expr must be set to the original expression being allocated for its locus
    909  1.1  mrg     and variable name in case a runtime error has to be printed.  */
    910  1.1  mrg void
    911  1.1  mrg gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
    912  1.1  mrg 			  tree token, tree status, tree errmsg, tree errlen,
    913  1.1  mrg 			  tree label_finish, gfc_expr* expr, int corank)
    914  1.1  mrg {
    915  1.1  mrg   stmtblock_t alloc_block;
    916  1.1  mrg   tree tmp, null_mem, alloc, error;
    917  1.1  mrg   tree type = TREE_TYPE (mem);
    918  1.1  mrg   symbol_attribute caf_attr;
    919  1.1  mrg   bool need_assign = false, refs_comp = false;
    920  1.1  mrg   gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
    921  1.1  mrg 
    922  1.1  mrg   size = fold_convert (size_type_node, size);
    923  1.1  mrg   null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
    924  1.1  mrg 					    logical_type_node, mem,
    925  1.1  mrg 					    build_int_cst (type, 0)),
    926  1.1  mrg 			   PRED_FORTRAN_REALLOC);
    927  1.1  mrg 
    928  1.1  mrg   /* If mem is NULL, we call gfc_allocate_using_malloc or
    929  1.1  mrg      gfc_allocate_using_lib.  */
    930  1.1  mrg   gfc_start_block (&alloc_block);
    931  1.1  mrg 
    932  1.1  mrg   if (flag_coarray == GFC_FCOARRAY_LIB)
    933  1.1  mrg     caf_attr = gfc_caf_attr (expr, true, &refs_comp);
    934  1.1  mrg 
    935  1.1  mrg   if (flag_coarray == GFC_FCOARRAY_LIB
    936  1.1  mrg       && (corank > 0 || caf_attr.codimension))
    937  1.1  mrg     {
    938  1.1  mrg       tree cond, sub_caf_tree;
    939  1.1  mrg       gfc_se se;
    940  1.1  mrg       bool compute_special_caf_types_size = false;
    941  1.1  mrg 
    942  1.1  mrg       if (expr->ts.type == BT_DERIVED
    943  1.1  mrg 	  && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
    944  1.1  mrg 	  && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
    945  1.1  mrg 	{
    946  1.1  mrg 	  compute_special_caf_types_size = true;
    947  1.1  mrg 	  caf_alloc_type = GFC_CAF_LOCK_ALLOC;
    948  1.1  mrg 	}
    949  1.1  mrg       else if (expr->ts.type == BT_DERIVED
    950  1.1  mrg 	       && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
    951  1.1  mrg 	       && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
    952  1.1  mrg 	{
    953  1.1  mrg 	  compute_special_caf_types_size = true;
    954  1.1  mrg 	  caf_alloc_type = GFC_CAF_EVENT_ALLOC;
    955  1.1  mrg 	}
    956  1.1  mrg       else if (!caf_attr.coarray_comp && refs_comp)
    957  1.1  mrg 	/* Only allocatable components in a derived type coarray can be
    958  1.1  mrg 	   allocate only.  */
    959  1.1  mrg 	caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
    960  1.1  mrg 
    961  1.1  mrg       gfc_init_se (&se, NULL);
    962  1.1  mrg       sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
    963  1.1  mrg       if (sub_caf_tree == NULL_TREE)
    964  1.1  mrg 	sub_caf_tree = token;
    965  1.1  mrg 
    966  1.1  mrg       /* When mem is an array ref, then strip the .data-ref.  */
    967  1.1  mrg       if (TREE_CODE (mem) == COMPONENT_REF
    968  1.1  mrg 	  && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
    969  1.1  mrg 	tmp = TREE_OPERAND (mem, 0);
    970  1.1  mrg       else
    971  1.1  mrg 	tmp = mem;
    972  1.1  mrg 
    973  1.1  mrg       if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
    974  1.1  mrg 	    && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
    975  1.1  mrg 	  && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
    976  1.1  mrg 	{
    977  1.1  mrg 	  symbol_attribute attr;
    978  1.1  mrg 
    979  1.1  mrg 	  gfc_clear_attr (&attr);
    980  1.1  mrg 	  tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
    981  1.1  mrg 	  need_assign = true;
    982  1.1  mrg 	}
    983  1.1  mrg       gfc_add_block_to_block (&alloc_block, &se.pre);
    984  1.1  mrg 
    985  1.1  mrg       /* In the front end, we represent the lock variable as pointer. However,
    986  1.1  mrg 	 the FE only passes the pointer around and leaves the actual
    987  1.1  mrg 	 representation to the library. Hence, we have to convert back to the
    988  1.1  mrg 	 number of elements.  */
    989  1.1  mrg       if (compute_special_caf_types_size)
    990  1.1  mrg 	size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
    991  1.1  mrg 				size, TYPE_SIZE_UNIT (ptr_type_node));
    992  1.1  mrg 
    993  1.1  mrg       gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
    994  1.1  mrg 				  status, errmsg, errlen, caf_alloc_type);
    995  1.1  mrg       if (need_assign)
    996  1.1  mrg 	gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
    997  1.1  mrg 					   gfc_conv_descriptor_data_get (tmp)));
    998  1.1  mrg       if (status != NULL_TREE)
    999  1.1  mrg 	{
   1000  1.1  mrg 	  TREE_USED (label_finish) = 1;
   1001  1.1  mrg 	  tmp = build1_v (GOTO_EXPR, label_finish);
   1002  1.1  mrg 	  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1003  1.1  mrg 				  status, build_zero_cst (TREE_TYPE (status)));
   1004  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1005  1.1  mrg 				 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
   1006  1.1  mrg 				 tmp, build_empty_stmt (input_location));
   1007  1.1  mrg 	  gfc_add_expr_to_block (&alloc_block, tmp);
   1008  1.1  mrg 	}
   1009  1.1  mrg     }
   1010  1.1  mrg   else
   1011  1.1  mrg     gfc_allocate_using_malloc (&alloc_block, mem, size, status);
   1012  1.1  mrg 
   1013  1.1  mrg   alloc = gfc_finish_block (&alloc_block);
   1014  1.1  mrg 
   1015  1.1  mrg   /* If mem is not NULL, we issue a runtime error or set the
   1016  1.1  mrg      status variable.  */
   1017  1.1  mrg   if (expr)
   1018  1.1  mrg     {
   1019  1.1  mrg       tree varname;
   1020  1.1  mrg 
   1021  1.1  mrg       gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
   1022  1.1  mrg       varname = gfc_build_cstring_const (expr->symtree->name);
   1023  1.1  mrg       varname = gfc_build_addr_expr (pchar_type_node, varname);
   1024  1.1  mrg 
   1025  1.1  mrg       error = gfc_trans_runtime_error (true, &expr->where,
   1026  1.1  mrg 				       "Attempting to allocate already"
   1027  1.1  mrg 				       " allocated variable '%s'",
   1028  1.1  mrg 				       varname);
   1029  1.1  mrg     }
   1030  1.1  mrg   else
   1031  1.1  mrg     error = gfc_trans_runtime_error (true, NULL,
   1032  1.1  mrg 				     "Attempting to allocate already allocated"
   1033  1.1  mrg 				     " variable");
   1034  1.1  mrg 
   1035  1.1  mrg   if (status != NULL_TREE)
   1036  1.1  mrg     {
   1037  1.1  mrg       tree status_type = TREE_TYPE (status);
   1038  1.1  mrg 
   1039  1.1  mrg       error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
   1040  1.1  mrg 	      status, build_int_cst (status_type, LIBERROR_ALLOCATION));
   1041  1.1  mrg     }
   1042  1.1  mrg 
   1043  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
   1044  1.1  mrg 			 error, alloc);
   1045  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1046  1.1  mrg }
   1047  1.1  mrg 
   1048  1.1  mrg 
   1049  1.1  mrg /* Free a given variable.  */
   1050  1.1  mrg 
   1051  1.1  mrg tree
   1052  1.1  mrg gfc_call_free (tree var)
   1053  1.1  mrg {
   1054  1.1  mrg   return build_call_expr_loc (input_location,
   1055  1.1  mrg 			      builtin_decl_explicit (BUILT_IN_FREE),
   1056  1.1  mrg 			      1, fold_convert (pvoid_type_node, var));
   1057  1.1  mrg }
   1058  1.1  mrg 
   1059  1.1  mrg 
   1060  1.1  mrg /* Build a call to a FINAL procedure, which finalizes "var".  */
   1061  1.1  mrg 
   1062  1.1  mrg static tree
   1063  1.1  mrg gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
   1064  1.1  mrg 		      bool fini_coarray, gfc_expr *class_size)
   1065  1.1  mrg {
   1066  1.1  mrg   stmtblock_t block;
   1067  1.1  mrg   gfc_se se;
   1068  1.1  mrg   tree final_fndecl, array, size, tmp;
   1069  1.1  mrg   symbol_attribute attr;
   1070  1.1  mrg 
   1071  1.1  mrg   gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
   1072  1.1  mrg   gcc_assert (var);
   1073  1.1  mrg 
   1074  1.1  mrg   gfc_start_block (&block);
   1075  1.1  mrg   gfc_init_se (&se, NULL);
   1076  1.1  mrg   gfc_conv_expr (&se, final_wrapper);
   1077  1.1  mrg   final_fndecl = se.expr;
   1078  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
   1079  1.1  mrg     final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
   1080  1.1  mrg 
   1081  1.1  mrg   if (ts.type == BT_DERIVED)
   1082  1.1  mrg     {
   1083  1.1  mrg       tree elem_size;
   1084  1.1  mrg 
   1085  1.1  mrg       gcc_assert (!class_size);
   1086  1.1  mrg       elem_size = gfc_typenode_for_spec (&ts);
   1087  1.1  mrg       elem_size = TYPE_SIZE_UNIT (elem_size);
   1088  1.1  mrg       size = fold_convert (gfc_array_index_type, elem_size);
   1089  1.1  mrg 
   1090  1.1  mrg       gfc_init_se (&se, NULL);
   1091  1.1  mrg       se.want_pointer = 1;
   1092  1.1  mrg       if (var->rank)
   1093  1.1  mrg 	{
   1094  1.1  mrg 	  se.descriptor_only = 1;
   1095  1.1  mrg 	  gfc_conv_expr_descriptor (&se, var);
   1096  1.1  mrg 	  array = se.expr;
   1097  1.1  mrg 	}
   1098  1.1  mrg       else
   1099  1.1  mrg 	{
   1100  1.1  mrg 	  gfc_conv_expr (&se, var);
   1101  1.1  mrg 	  gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
   1102  1.1  mrg 	  array = se.expr;
   1103  1.1  mrg 
   1104  1.1  mrg 	  /* No copy back needed, hence set attr's allocatable/pointer
   1105  1.1  mrg 	     to zero.  */
   1106  1.1  mrg 	  gfc_clear_attr (&attr);
   1107  1.1  mrg 	  gfc_init_se (&se, NULL);
   1108  1.1  mrg 	  array = gfc_conv_scalar_to_descriptor (&se, array, attr);
   1109  1.1  mrg 	  gcc_assert (se.post.head == NULL_TREE);
   1110  1.1  mrg 	}
   1111  1.1  mrg     }
   1112  1.1  mrg   else
   1113  1.1  mrg     {
   1114  1.1  mrg       gfc_expr *array_expr;
   1115  1.1  mrg       gcc_assert (class_size);
   1116  1.1  mrg       gfc_init_se (&se, NULL);
   1117  1.1  mrg       gfc_conv_expr (&se, class_size);
   1118  1.1  mrg       gfc_add_block_to_block (&block, &se.pre);
   1119  1.1  mrg       gcc_assert (se.post.head == NULL_TREE);
   1120  1.1  mrg       size = se.expr;
   1121  1.1  mrg 
   1122  1.1  mrg       array_expr = gfc_copy_expr (var);
   1123  1.1  mrg       gfc_init_se (&se, NULL);
   1124  1.1  mrg       se.want_pointer = 1;
   1125  1.1  mrg       if (array_expr->rank)
   1126  1.1  mrg 	{
   1127  1.1  mrg 	  gfc_add_class_array_ref (array_expr);
   1128  1.1  mrg 	  se.descriptor_only = 1;
   1129  1.1  mrg 	  gfc_conv_expr_descriptor (&se, array_expr);
   1130  1.1  mrg 	  array = se.expr;
   1131  1.1  mrg 	}
   1132  1.1  mrg       else
   1133  1.1  mrg 	{
   1134  1.1  mrg 	  gfc_add_data_component (array_expr);
   1135  1.1  mrg 	  gfc_conv_expr (&se, array_expr);
   1136  1.1  mrg 	  gfc_add_block_to_block (&block, &se.pre);
   1137  1.1  mrg 	  gcc_assert (se.post.head == NULL_TREE);
   1138  1.1  mrg 	  array = se.expr;
   1139  1.1  mrg 
   1140  1.1  mrg 	  if (!gfc_is_coarray (array_expr))
   1141  1.1  mrg 	    {
   1142  1.1  mrg 	      /* No copy back needed, hence set attr's allocatable/pointer
   1143  1.1  mrg 		 to zero.  */
   1144  1.1  mrg 	      gfc_clear_attr (&attr);
   1145  1.1  mrg 	      gfc_init_se (&se, NULL);
   1146  1.1  mrg 	      array = gfc_conv_scalar_to_descriptor (&se, array, attr);
   1147  1.1  mrg 	    }
   1148  1.1  mrg 	  gcc_assert (se.post.head == NULL_TREE);
   1149  1.1  mrg 	}
   1150  1.1  mrg       gfc_free_expr (array_expr);
   1151  1.1  mrg     }
   1152  1.1  mrg 
   1153  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (array)))
   1154  1.1  mrg     array = gfc_build_addr_expr (NULL, array);
   1155  1.1  mrg 
   1156  1.1  mrg   gfc_add_block_to_block (&block, &se.pre);
   1157  1.1  mrg   tmp = build_call_expr_loc (input_location,
   1158  1.1  mrg 			     final_fndecl, 3, array,
   1159  1.1  mrg 			     size, fini_coarray ? boolean_true_node
   1160  1.1  mrg 						: boolean_false_node);
   1161  1.1  mrg   gfc_add_block_to_block (&block, &se.post);
   1162  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   1163  1.1  mrg   return gfc_finish_block (&block);
   1164  1.1  mrg }
   1165  1.1  mrg 
   1166  1.1  mrg 
   1167  1.1  mrg bool
   1168  1.1  mrg gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
   1169  1.1  mrg 			     bool fini_coarray)
   1170  1.1  mrg {
   1171  1.1  mrg   gfc_se se;
   1172  1.1  mrg   stmtblock_t block2;
   1173  1.1  mrg   tree final_fndecl, size, array, tmp, cond;
   1174  1.1  mrg   symbol_attribute attr;
   1175  1.1  mrg   gfc_expr *final_expr = NULL;
   1176  1.1  mrg 
   1177  1.1  mrg   if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
   1178  1.1  mrg     return false;
   1179  1.1  mrg 
   1180  1.1  mrg   gfc_init_block (&block2);
   1181  1.1  mrg 
   1182  1.1  mrg   if (comp->ts.type == BT_DERIVED)
   1183  1.1  mrg     {
   1184  1.1  mrg       if (comp->attr.pointer)
   1185  1.1  mrg 	return false;
   1186  1.1  mrg 
   1187  1.1  mrg       gfc_is_finalizable (comp->ts.u.derived, &final_expr);
   1188  1.1  mrg       if (!final_expr)
   1189  1.1  mrg         return false;
   1190  1.1  mrg 
   1191  1.1  mrg       gfc_init_se (&se, NULL);
   1192  1.1  mrg       gfc_conv_expr (&se, final_expr);
   1193  1.1  mrg       final_fndecl = se.expr;
   1194  1.1  mrg       size = gfc_typenode_for_spec (&comp->ts);
   1195  1.1  mrg       size = TYPE_SIZE_UNIT (size);
   1196  1.1  mrg       size = fold_convert (gfc_array_index_type, size);
   1197  1.1  mrg 
   1198  1.1  mrg       array = decl;
   1199  1.1  mrg     }
   1200  1.1  mrg   else /* comp->ts.type == BT_CLASS.  */
   1201  1.1  mrg     {
   1202  1.1  mrg       if (CLASS_DATA (comp)->attr.class_pointer)
   1203  1.1  mrg 	return false;
   1204  1.1  mrg 
   1205  1.1  mrg       gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
   1206  1.1  mrg       final_fndecl = gfc_class_vtab_final_get (decl);
   1207  1.1  mrg       size = gfc_class_vtab_size_get (decl);
   1208  1.1  mrg       array = gfc_class_data_get (decl);
   1209  1.1  mrg     }
   1210  1.1  mrg 
   1211  1.1  mrg   if (comp->attr.allocatable
   1212  1.1  mrg       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
   1213  1.1  mrg     {
   1214  1.1  mrg       tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
   1215  1.1  mrg 	    ?  gfc_conv_descriptor_data_get (array) : array;
   1216  1.1  mrg       cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1217  1.1  mrg 			    tmp, fold_convert (TREE_TYPE (tmp),
   1218  1.1  mrg 						 null_pointer_node));
   1219  1.1  mrg     }
   1220  1.1  mrg   else
   1221  1.1  mrg     cond = logical_true_node;
   1222  1.1  mrg 
   1223  1.1  mrg   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
   1224  1.1  mrg     {
   1225  1.1  mrg       gfc_clear_attr (&attr);
   1226  1.1  mrg       gfc_init_se (&se, NULL);
   1227  1.1  mrg       array = gfc_conv_scalar_to_descriptor (&se, array, attr);
   1228  1.1  mrg       gfc_add_block_to_block (&block2, &se.pre);
   1229  1.1  mrg       gcc_assert (se.post.head == NULL_TREE);
   1230  1.1  mrg     }
   1231  1.1  mrg 
   1232  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (array)))
   1233  1.1  mrg     array = gfc_build_addr_expr (NULL, array);
   1234  1.1  mrg 
   1235  1.1  mrg   if (!final_expr)
   1236  1.1  mrg     {
   1237  1.1  mrg       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1238  1.1  mrg 			     final_fndecl,
   1239  1.1  mrg 			     fold_convert (TREE_TYPE (final_fndecl),
   1240  1.1  mrg 					   null_pointer_node));
   1241  1.1  mrg       cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   1242  1.1  mrg 			      logical_type_node, cond, tmp);
   1243  1.1  mrg     }
   1244  1.1  mrg 
   1245  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
   1246  1.1  mrg     final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
   1247  1.1  mrg 
   1248  1.1  mrg   tmp = build_call_expr_loc (input_location,
   1249  1.1  mrg 			     final_fndecl, 3, array,
   1250  1.1  mrg 			     size, fini_coarray ? boolean_true_node
   1251  1.1  mrg 						: boolean_false_node);
   1252  1.1  mrg   gfc_add_expr_to_block (&block2, tmp);
   1253  1.1  mrg   tmp = gfc_finish_block (&block2);
   1254  1.1  mrg 
   1255  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
   1256  1.1  mrg 			 build_empty_stmt (input_location));
   1257  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1258  1.1  mrg 
   1259  1.1  mrg   return true;
   1260  1.1  mrg }
   1261  1.1  mrg 
   1262  1.1  mrg 
   1263  1.1  mrg /* Add a call to the finalizer, using the passed *expr. Returns
   1264  1.1  mrg    true when a finalizer call has been inserted.  */
   1265  1.1  mrg 
   1266  1.1  mrg bool
   1267  1.1  mrg gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
   1268  1.1  mrg {
   1269  1.1  mrg   tree tmp;
   1270  1.1  mrg   gfc_ref *ref;
   1271  1.1  mrg   gfc_expr *expr;
   1272  1.1  mrg   gfc_expr *final_expr = NULL;
   1273  1.1  mrg   gfc_expr *elem_size = NULL;
   1274  1.1  mrg   bool has_finalizer = false;
   1275  1.1  mrg 
   1276  1.1  mrg   if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
   1277  1.1  mrg     return false;
   1278  1.1  mrg 
   1279  1.1  mrg   if (expr2->ts.type == BT_DERIVED)
   1280  1.1  mrg     {
   1281  1.1  mrg       gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
   1282  1.1  mrg       if (!final_expr)
   1283  1.1  mrg         return false;
   1284  1.1  mrg     }
   1285  1.1  mrg 
   1286  1.1  mrg   /* If we have a class array, we need go back to the class
   1287  1.1  mrg      container.  */
   1288  1.1  mrg   expr = gfc_copy_expr (expr2);
   1289  1.1  mrg 
   1290  1.1  mrg   if (expr->ref && expr->ref->next && !expr->ref->next->next
   1291  1.1  mrg       && expr->ref->next->type == REF_ARRAY
   1292  1.1  mrg       && expr->ref->type == REF_COMPONENT
   1293  1.1  mrg       && strcmp (expr->ref->u.c.component->name, "_data") == 0)
   1294  1.1  mrg     {
   1295  1.1  mrg       gfc_free_ref_list (expr->ref);
   1296  1.1  mrg       expr->ref = NULL;
   1297  1.1  mrg     }
   1298  1.1  mrg   else
   1299  1.1  mrg     for (ref = expr->ref; ref; ref = ref->next)
   1300  1.1  mrg       if (ref->next && ref->next->next && !ref->next->next->next
   1301  1.1  mrg          && ref->next->next->type == REF_ARRAY
   1302  1.1  mrg          && ref->next->type == REF_COMPONENT
   1303  1.1  mrg          && strcmp (ref->next->u.c.component->name, "_data") == 0)
   1304  1.1  mrg        {
   1305  1.1  mrg          gfc_free_ref_list (ref->next);
   1306  1.1  mrg          ref->next = NULL;
   1307  1.1  mrg        }
   1308  1.1  mrg 
   1309  1.1  mrg   if (expr->ts.type == BT_CLASS)
   1310  1.1  mrg     {
   1311  1.1  mrg       has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
   1312  1.1  mrg 
   1313  1.1  mrg       if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
   1314  1.1  mrg 	expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
   1315  1.1  mrg 
   1316  1.1  mrg       final_expr = gfc_copy_expr (expr);
   1317  1.1  mrg       gfc_add_vptr_component (final_expr);
   1318  1.1  mrg       gfc_add_final_component (final_expr);
   1319  1.1  mrg 
   1320  1.1  mrg       elem_size = gfc_copy_expr (expr);
   1321  1.1  mrg       gfc_add_vptr_component (elem_size);
   1322  1.1  mrg       gfc_add_size_component (elem_size);
   1323  1.1  mrg     }
   1324  1.1  mrg 
   1325  1.1  mrg   gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
   1326  1.1  mrg 
   1327  1.1  mrg   tmp = gfc_build_final_call (expr->ts, final_expr, expr,
   1328  1.1  mrg 			      false, elem_size);
   1329  1.1  mrg 
   1330  1.1  mrg   if (expr->ts.type == BT_CLASS && !has_finalizer)
   1331  1.1  mrg     {
   1332  1.1  mrg       tree cond;
   1333  1.1  mrg       gfc_se se;
   1334  1.1  mrg 
   1335  1.1  mrg       gfc_init_se (&se, NULL);
   1336  1.1  mrg       se.want_pointer = 1;
   1337  1.1  mrg       gfc_conv_expr (&se, final_expr);
   1338  1.1  mrg       cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1339  1.1  mrg 			      se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
   1340  1.1  mrg 
   1341  1.1  mrg       /* For CLASS(*) not only sym->_vtab->_final can be NULL
   1342  1.1  mrg 	 but already sym->_vtab itself.  */
   1343  1.1  mrg       if (UNLIMITED_POLY (expr))
   1344  1.1  mrg 	{
   1345  1.1  mrg 	  tree cond2;
   1346  1.1  mrg 	  gfc_expr *vptr_expr;
   1347  1.1  mrg 
   1348  1.1  mrg 	  vptr_expr = gfc_copy_expr (expr);
   1349  1.1  mrg 	  gfc_add_vptr_component (vptr_expr);
   1350  1.1  mrg 
   1351  1.1  mrg 	  gfc_init_se (&se, NULL);
   1352  1.1  mrg 	  se.want_pointer = 1;
   1353  1.1  mrg 	  gfc_conv_expr (&se, vptr_expr);
   1354  1.1  mrg 	  gfc_free_expr (vptr_expr);
   1355  1.1  mrg 
   1356  1.1  mrg 	  cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1357  1.1  mrg 				   se.expr,
   1358  1.1  mrg 				   build_int_cst (TREE_TYPE (se.expr), 0));
   1359  1.1  mrg 	  cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   1360  1.1  mrg 				  logical_type_node, cond2, cond);
   1361  1.1  mrg 	}
   1362  1.1  mrg 
   1363  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1364  1.1  mrg 			     cond, tmp, build_empty_stmt (input_location));
   1365  1.1  mrg     }
   1366  1.1  mrg 
   1367  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1368  1.1  mrg 
   1369  1.1  mrg   return true;
   1370  1.1  mrg }
   1371  1.1  mrg 
   1372  1.1  mrg 
   1373  1.1  mrg /* User-deallocate; we emit the code directly from the front-end, and the
   1374  1.1  mrg    logic is the same as the previous library function:
   1375  1.1  mrg 
   1376  1.1  mrg     void
   1377  1.1  mrg     deallocate (void *pointer, GFC_INTEGER_4 * stat)
   1378  1.1  mrg     {
   1379  1.1  mrg       if (!pointer)
   1380  1.1  mrg 	{
   1381  1.1  mrg 	  if (stat)
   1382  1.1  mrg 	    *stat = 1;
   1383  1.1  mrg 	  else
   1384  1.1  mrg 	    runtime_error ("Attempt to DEALLOCATE unallocated memory.");
   1385  1.1  mrg 	}
   1386  1.1  mrg       else
   1387  1.1  mrg 	{
   1388  1.1  mrg 	  free (pointer);
   1389  1.1  mrg 	  if (stat)
   1390  1.1  mrg 	    *stat = 0;
   1391  1.1  mrg 	}
   1392  1.1  mrg     }
   1393  1.1  mrg 
   1394  1.1  mrg    In this front-end version, status doesn't have to be GFC_INTEGER_4.
   1395  1.1  mrg    Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
   1396  1.1  mrg    even when no status variable is passed to us (this is used for
   1397  1.1  mrg    unconditional deallocation generated by the front-end at end of
   1398  1.1  mrg    each procedure).
   1399  1.1  mrg 
   1400  1.1  mrg    If a runtime-message is possible, `expr' must point to the original
   1401  1.1  mrg    expression being deallocated for its locus and variable name.
   1402  1.1  mrg 
   1403  1.1  mrg    For coarrays, "pointer" must be the array descriptor and not its
   1404  1.1  mrg    "data" component.
   1405  1.1  mrg 
   1406  1.1  mrg    COARRAY_DEALLOC_MODE gives the mode unregister coarrays.  Available modes are
   1407  1.1  mrg    the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
   1408  1.1  mrg    analyzed and set by this routine, and -2 to indicate that a non-coarray is to
   1409  1.1  mrg    be deallocated.  */
   1410  1.1  mrg tree
   1411  1.1  mrg gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
   1412  1.1  mrg 			    tree errlen, tree label_finish,
   1413  1.1  mrg 			    bool can_fail, gfc_expr* expr,
   1414  1.1  mrg 			    int coarray_dealloc_mode, tree add_when_allocated,
   1415  1.1  mrg 			    tree caf_token)
   1416  1.1  mrg {
   1417  1.1  mrg   stmtblock_t null, non_null;
   1418  1.1  mrg   tree cond, tmp, error;
   1419  1.1  mrg   tree status_type = NULL_TREE;
   1420  1.1  mrg   tree token = NULL_TREE;
   1421  1.1  mrg   gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
   1422  1.1  mrg 
   1423  1.1  mrg   if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
   1424  1.1  mrg     {
   1425  1.1  mrg       if (flag_coarray == GFC_FCOARRAY_LIB)
   1426  1.1  mrg 	{
   1427  1.1  mrg 	  if (caf_token)
   1428  1.1  mrg 	    token = caf_token;
   1429  1.1  mrg 	  else
   1430  1.1  mrg 	    {
   1431  1.1  mrg 	      tree caf_type, caf_decl = pointer;
   1432  1.1  mrg 	      pointer = gfc_conv_descriptor_data_get (caf_decl);
   1433  1.1  mrg 	      caf_type = TREE_TYPE (caf_decl);
   1434  1.1  mrg 	      STRIP_NOPS (pointer);
   1435  1.1  mrg 	      if (GFC_DESCRIPTOR_TYPE_P (caf_type))
   1436  1.1  mrg 		token = gfc_conv_descriptor_token (caf_decl);
   1437  1.1  mrg 	      else if (DECL_LANG_SPECIFIC (caf_decl)
   1438  1.1  mrg 		       && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
   1439  1.1  mrg 		token = GFC_DECL_TOKEN (caf_decl);
   1440  1.1  mrg 	      else
   1441  1.1  mrg 		{
   1442  1.1  mrg 		  gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
   1443  1.1  mrg 			      && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
   1444  1.1  mrg 				 != NULL_TREE);
   1445  1.1  mrg 		  token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
   1446  1.1  mrg 		}
   1447  1.1  mrg 	    }
   1448  1.1  mrg 
   1449  1.1  mrg 	  if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
   1450  1.1  mrg 	    {
   1451  1.1  mrg 	      bool comp_ref;
   1452  1.1  mrg 	      if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
   1453  1.1  mrg 		  && comp_ref)
   1454  1.1  mrg 		caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
   1455  1.1  mrg 	      // else do a deregister as set by default.
   1456  1.1  mrg 	    }
   1457  1.1  mrg 	  else
   1458  1.1  mrg 	    caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
   1459  1.1  mrg 	}
   1460  1.1  mrg       else if (flag_coarray == GFC_FCOARRAY_SINGLE)
   1461  1.1  mrg 	pointer = gfc_conv_descriptor_data_get (pointer);
   1462  1.1  mrg     }
   1463  1.1  mrg   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
   1464  1.1  mrg     pointer = gfc_conv_descriptor_data_get (pointer);
   1465  1.1  mrg 
   1466  1.1  mrg   cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
   1467  1.1  mrg 			  build_int_cst (TREE_TYPE (pointer), 0));
   1468  1.1  mrg 
   1469  1.1  mrg   /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
   1470  1.1  mrg      we emit a runtime error.  */
   1471  1.1  mrg   gfc_start_block (&null);
   1472  1.1  mrg   if (!can_fail)
   1473  1.1  mrg     {
   1474  1.1  mrg       tree varname;
   1475  1.1  mrg 
   1476  1.1  mrg       gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
   1477  1.1  mrg 
   1478  1.1  mrg       varname = gfc_build_cstring_const (expr->symtree->name);
   1479  1.1  mrg       varname = gfc_build_addr_expr (pchar_type_node, varname);
   1480  1.1  mrg 
   1481  1.1  mrg       error = gfc_trans_runtime_error (true, &expr->where,
   1482  1.1  mrg 				       "Attempt to DEALLOCATE unallocated '%s'",
   1483  1.1  mrg 				       varname);
   1484  1.1  mrg     }
   1485  1.1  mrg   else
   1486  1.1  mrg     error = build_empty_stmt (input_location);
   1487  1.1  mrg 
   1488  1.1  mrg   if (status != NULL_TREE && !integer_zerop (status))
   1489  1.1  mrg     {
   1490  1.1  mrg       tree cond2;
   1491  1.1  mrg 
   1492  1.1  mrg       status_type = TREE_TYPE (TREE_TYPE (status));
   1493  1.1  mrg       cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1494  1.1  mrg 			       status, build_int_cst (TREE_TYPE (status), 0));
   1495  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
   1496  1.1  mrg 			     fold_build1_loc (input_location, INDIRECT_REF,
   1497  1.1  mrg 					      status_type, status),
   1498  1.1  mrg 			     build_int_cst (status_type, 1));
   1499  1.1  mrg       error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1500  1.1  mrg 			       cond2, tmp, error);
   1501  1.1  mrg     }
   1502  1.1  mrg 
   1503  1.1  mrg   gfc_add_expr_to_block (&null, error);
   1504  1.1  mrg 
   1505  1.1  mrg   /* When POINTER is not NULL, we free it.  */
   1506  1.1  mrg   gfc_start_block (&non_null);
   1507  1.1  mrg   if (add_when_allocated)
   1508  1.1  mrg     gfc_add_expr_to_block (&non_null, add_when_allocated);
   1509  1.1  mrg   gfc_add_finalizer_call (&non_null, expr);
   1510  1.1  mrg   if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
   1511  1.1  mrg       || flag_coarray != GFC_FCOARRAY_LIB)
   1512  1.1  mrg     {
   1513  1.1  mrg       tmp = build_call_expr_loc (input_location,
   1514  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_FREE), 1,
   1515  1.1  mrg 				 fold_convert (pvoid_type_node, pointer));
   1516  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1517  1.1  mrg       gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
   1518  1.1  mrg 							 0));
   1519  1.1  mrg 
   1520  1.1  mrg       if (status != NULL_TREE && !integer_zerop (status))
   1521  1.1  mrg 	{
   1522  1.1  mrg 	  /* We set STATUS to zero if it is present.  */
   1523  1.1  mrg 	  tree status_type = TREE_TYPE (TREE_TYPE (status));
   1524  1.1  mrg 	  tree cond2;
   1525  1.1  mrg 
   1526  1.1  mrg 	  cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1527  1.1  mrg 				   status,
   1528  1.1  mrg 				   build_int_cst (TREE_TYPE (status), 0));
   1529  1.1  mrg 	  tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
   1530  1.1  mrg 				 fold_build1_loc (input_location, INDIRECT_REF,
   1531  1.1  mrg 						  status_type, status),
   1532  1.1  mrg 				 build_int_cst (status_type, 0));
   1533  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1534  1.1  mrg 				 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
   1535  1.1  mrg 				 tmp, build_empty_stmt (input_location));
   1536  1.1  mrg 	  gfc_add_expr_to_block (&non_null, tmp);
   1537  1.1  mrg 	}
   1538  1.1  mrg     }
   1539  1.1  mrg   else
   1540  1.1  mrg     {
   1541  1.1  mrg       tree cond2, pstat = null_pointer_node;
   1542  1.1  mrg 
   1543  1.1  mrg       if (errmsg == NULL_TREE)
   1544  1.1  mrg 	{
   1545  1.1  mrg 	  gcc_assert (errlen == NULL_TREE);
   1546  1.1  mrg 	  errmsg = null_pointer_node;
   1547  1.1  mrg 	  errlen = build_zero_cst (integer_type_node);
   1548  1.1  mrg 	}
   1549  1.1  mrg       else
   1550  1.1  mrg 	{
   1551  1.1  mrg 	  gcc_assert (errlen != NULL_TREE);
   1552  1.1  mrg 	  if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
   1553  1.1  mrg 	    errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
   1554  1.1  mrg 	}
   1555  1.1  mrg 
   1556  1.1  mrg       if (status != NULL_TREE && !integer_zerop (status))
   1557  1.1  mrg 	{
   1558  1.1  mrg 	  gcc_assert (status_type == integer_type_node);
   1559  1.1  mrg 	  pstat = status;
   1560  1.1  mrg 	}
   1561  1.1  mrg 
   1562  1.1  mrg       token = gfc_build_addr_expr  (NULL_TREE, token);
   1563  1.1  mrg       gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
   1564  1.1  mrg       tmp = build_call_expr_loc (input_location,
   1565  1.1  mrg 				 gfor_fndecl_caf_deregister, 5,
   1566  1.1  mrg 				 token, build_int_cst (integer_type_node,
   1567  1.1  mrg 						       caf_dereg_type),
   1568  1.1  mrg 				 pstat, errmsg, errlen);
   1569  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1570  1.1  mrg 
   1571  1.1  mrg       /* It guarantees memory consistency within the same segment */
   1572  1.1  mrg       tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
   1573  1.1  mrg       tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
   1574  1.1  mrg 			gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
   1575  1.1  mrg 			tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
   1576  1.1  mrg       ASM_VOLATILE_P (tmp) = 1;
   1577  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1578  1.1  mrg 
   1579  1.1  mrg       if (status != NULL_TREE)
   1580  1.1  mrg 	{
   1581  1.1  mrg 	  tree stat = build_fold_indirect_ref_loc (input_location, status);
   1582  1.1  mrg 	  tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
   1583  1.1  mrg 					  void_type_node, pointer,
   1584  1.1  mrg 					  build_int_cst (TREE_TYPE (pointer),
   1585  1.1  mrg 							 0));
   1586  1.1  mrg 
   1587  1.1  mrg 	  TREE_USED (label_finish) = 1;
   1588  1.1  mrg 	  tmp = build1_v (GOTO_EXPR, label_finish);
   1589  1.1  mrg 	  cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1590  1.1  mrg 				   stat, build_zero_cst (TREE_TYPE (stat)));
   1591  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1592  1.1  mrg 				 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
   1593  1.1  mrg 				 tmp, nullify);
   1594  1.1  mrg 	  gfc_add_expr_to_block (&non_null, tmp);
   1595  1.1  mrg 	}
   1596  1.1  mrg       else
   1597  1.1  mrg 	gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
   1598  1.1  mrg 							   0));
   1599  1.1  mrg     }
   1600  1.1  mrg 
   1601  1.1  mrg   return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   1602  1.1  mrg 			  gfc_finish_block (&null),
   1603  1.1  mrg 			  gfc_finish_block (&non_null));
   1604  1.1  mrg }
   1605  1.1  mrg 
   1606  1.1  mrg 
   1607  1.1  mrg /* Generate code for deallocation of allocatable scalars (variables or
   1608  1.1  mrg    components). Before the object itself is freed, any allocatable
   1609  1.1  mrg    subcomponents are being deallocated.  */
   1610  1.1  mrg 
   1611  1.1  mrg tree
   1612  1.1  mrg gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
   1613  1.1  mrg 				   bool can_fail, gfc_expr* expr,
   1614  1.1  mrg 				   gfc_typespec ts, bool coarray)
   1615  1.1  mrg {
   1616  1.1  mrg   stmtblock_t null, non_null;
   1617  1.1  mrg   tree cond, tmp, error;
   1618  1.1  mrg   bool finalizable, comp_ref;
   1619  1.1  mrg   gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
   1620  1.1  mrg 
   1621  1.1  mrg   if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
   1622  1.1  mrg       && comp_ref)
   1623  1.1  mrg     caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
   1624  1.1  mrg 
   1625  1.1  mrg   cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
   1626  1.1  mrg 			  build_int_cst (TREE_TYPE (pointer), 0));
   1627  1.1  mrg 
   1628  1.1  mrg   /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
   1629  1.1  mrg      we emit a runtime error.  */
   1630  1.1  mrg   gfc_start_block (&null);
   1631  1.1  mrg   if (!can_fail)
   1632  1.1  mrg     {
   1633  1.1  mrg       tree varname;
   1634  1.1  mrg 
   1635  1.1  mrg       gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
   1636  1.1  mrg 
   1637  1.1  mrg       varname = gfc_build_cstring_const (expr->symtree->name);
   1638  1.1  mrg       varname = gfc_build_addr_expr (pchar_type_node, varname);
   1639  1.1  mrg 
   1640  1.1  mrg       error = gfc_trans_runtime_error (true, &expr->where,
   1641  1.1  mrg 				       "Attempt to DEALLOCATE unallocated '%s'",
   1642  1.1  mrg 				       varname);
   1643  1.1  mrg     }
   1644  1.1  mrg   else
   1645  1.1  mrg     error = build_empty_stmt (input_location);
   1646  1.1  mrg 
   1647  1.1  mrg   if (status != NULL_TREE && !integer_zerop (status))
   1648  1.1  mrg     {
   1649  1.1  mrg       tree status_type = TREE_TYPE (TREE_TYPE (status));
   1650  1.1  mrg       tree cond2;
   1651  1.1  mrg 
   1652  1.1  mrg       cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1653  1.1  mrg 			       status, build_int_cst (TREE_TYPE (status), 0));
   1654  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
   1655  1.1  mrg 			     fold_build1_loc (input_location, INDIRECT_REF,
   1656  1.1  mrg 					      status_type, status),
   1657  1.1  mrg 			     build_int_cst (status_type, 1));
   1658  1.1  mrg       error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1659  1.1  mrg 			       cond2, tmp, error);
   1660  1.1  mrg     }
   1661  1.1  mrg   gfc_add_expr_to_block (&null, error);
   1662  1.1  mrg 
   1663  1.1  mrg   /* When POINTER is not NULL, we free it.  */
   1664  1.1  mrg   gfc_start_block (&non_null);
   1665  1.1  mrg 
   1666  1.1  mrg   /* Free allocatable components.  */
   1667  1.1  mrg   finalizable = gfc_add_finalizer_call (&non_null, expr);
   1668  1.1  mrg   if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
   1669  1.1  mrg     {
   1670  1.1  mrg       int caf_mode = coarray
   1671  1.1  mrg 	  ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
   1672  1.1  mrg 	      ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
   1673  1.1  mrg 	     | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
   1674  1.1  mrg 	     | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
   1675  1.1  mrg 	  : 0;
   1676  1.1  mrg       if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
   1677  1.1  mrg 	tmp = gfc_conv_descriptor_data_get (pointer);
   1678  1.1  mrg       else
   1679  1.1  mrg 	tmp = build_fold_indirect_ref_loc (input_location, pointer);
   1680  1.1  mrg       tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
   1681  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1682  1.1  mrg     }
   1683  1.1  mrg 
   1684  1.1  mrg   if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
   1685  1.1  mrg     {
   1686  1.1  mrg       tmp = build_call_expr_loc (input_location,
   1687  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_FREE), 1,
   1688  1.1  mrg 				 fold_convert (pvoid_type_node, pointer));
   1689  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1690  1.1  mrg 
   1691  1.1  mrg       if (status != NULL_TREE && !integer_zerop (status))
   1692  1.1  mrg 	{
   1693  1.1  mrg 	  /* We set STATUS to zero if it is present.  */
   1694  1.1  mrg 	  tree status_type = TREE_TYPE (TREE_TYPE (status));
   1695  1.1  mrg 	  tree cond2;
   1696  1.1  mrg 
   1697  1.1  mrg 	  cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1698  1.1  mrg 				   status,
   1699  1.1  mrg 				   build_int_cst (TREE_TYPE (status), 0));
   1700  1.1  mrg 	  tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
   1701  1.1  mrg 				 fold_build1_loc (input_location, INDIRECT_REF,
   1702  1.1  mrg 						  status_type, status),
   1703  1.1  mrg 				 build_int_cst (status_type, 0));
   1704  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1705  1.1  mrg 				 cond2, tmp, build_empty_stmt (input_location));
   1706  1.1  mrg 	  gfc_add_expr_to_block (&non_null, tmp);
   1707  1.1  mrg 	}
   1708  1.1  mrg     }
   1709  1.1  mrg   else
   1710  1.1  mrg     {
   1711  1.1  mrg       tree token;
   1712  1.1  mrg       tree pstat = null_pointer_node;
   1713  1.1  mrg       gfc_se se;
   1714  1.1  mrg 
   1715  1.1  mrg       gfc_init_se (&se, NULL);
   1716  1.1  mrg       token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
   1717  1.1  mrg       gcc_assert (token != NULL_TREE);
   1718  1.1  mrg 
   1719  1.1  mrg       if (status != NULL_TREE && !integer_zerop (status))
   1720  1.1  mrg 	{
   1721  1.1  mrg 	  gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
   1722  1.1  mrg 	  pstat = status;
   1723  1.1  mrg 	}
   1724  1.1  mrg 
   1725  1.1  mrg       tmp = build_call_expr_loc (input_location,
   1726  1.1  mrg 				 gfor_fndecl_caf_deregister, 5,
   1727  1.1  mrg 				 token, build_int_cst (integer_type_node,
   1728  1.1  mrg 						       caf_dereg_type),
   1729  1.1  mrg 				 pstat, null_pointer_node, integer_zero_node);
   1730  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1731  1.1  mrg 
   1732  1.1  mrg       /* It guarantees memory consistency within the same segment.  */
   1733  1.1  mrg       tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
   1734  1.1  mrg       tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
   1735  1.1  mrg 			gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
   1736  1.1  mrg 			tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
   1737  1.1  mrg       ASM_VOLATILE_P (tmp) = 1;
   1738  1.1  mrg       gfc_add_expr_to_block (&non_null, tmp);
   1739  1.1  mrg 
   1740  1.1  mrg       if (status != NULL_TREE)
   1741  1.1  mrg 	{
   1742  1.1  mrg 	  tree stat = build_fold_indirect_ref_loc (input_location, status);
   1743  1.1  mrg 	  tree cond2;
   1744  1.1  mrg 
   1745  1.1  mrg 	  TREE_USED (label_finish) = 1;
   1746  1.1  mrg 	  tmp = build1_v (GOTO_EXPR, label_finish);
   1747  1.1  mrg 	  cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1748  1.1  mrg 				   stat, build_zero_cst (TREE_TYPE (stat)));
   1749  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1750  1.1  mrg 				 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
   1751  1.1  mrg 				 tmp, build_empty_stmt (input_location));
   1752  1.1  mrg 	  gfc_add_expr_to_block (&non_null, tmp);
   1753  1.1  mrg 	}
   1754  1.1  mrg     }
   1755  1.1  mrg 
   1756  1.1  mrg   return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   1757  1.1  mrg 			  gfc_finish_block (&null),
   1758  1.1  mrg 			  gfc_finish_block (&non_null));
   1759  1.1  mrg }
   1760  1.1  mrg 
   1761  1.1  mrg /* Reallocate MEM so it has SIZE bytes of data.  This behaves like the
   1762  1.1  mrg    following pseudo-code:
   1763  1.1  mrg 
   1764  1.1  mrg void *
   1765  1.1  mrg internal_realloc (void *mem, size_t size)
   1766  1.1  mrg {
   1767  1.1  mrg   res = realloc (mem, size);
   1768  1.1  mrg   if (!res && size != 0)
   1769  1.1  mrg     _gfortran_os_error ("Allocation would exceed memory limit");
   1770  1.1  mrg 
   1771  1.1  mrg   return res;
   1772  1.1  mrg }  */
   1773  1.1  mrg tree
   1774  1.1  mrg gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
   1775  1.1  mrg {
   1776  1.1  mrg   tree res, nonzero, null_result, tmp;
   1777  1.1  mrg   tree type = TREE_TYPE (mem);
   1778  1.1  mrg 
   1779  1.1  mrg   /* Only evaluate the size once.  */
   1780  1.1  mrg   size = save_expr (fold_convert (size_type_node, size));
   1781  1.1  mrg 
   1782  1.1  mrg   /* Create a variable to hold the result.  */
   1783  1.1  mrg   res = gfc_create_var (type, NULL);
   1784  1.1  mrg 
   1785  1.1  mrg   /* Call realloc and check the result.  */
   1786  1.1  mrg   tmp = build_call_expr_loc (input_location,
   1787  1.1  mrg 			 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
   1788  1.1  mrg 			 fold_convert (pvoid_type_node, mem), size);
   1789  1.1  mrg   gfc_add_modify (block, res, fold_convert (type, tmp));
   1790  1.1  mrg   null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   1791  1.1  mrg 				 res, build_int_cst (pvoid_type_node, 0));
   1792  1.1  mrg   nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
   1793  1.1  mrg 			     build_int_cst (size_type_node, 0));
   1794  1.1  mrg   null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
   1795  1.1  mrg 				 null_result, nonzero);
   1796  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   1797  1.1  mrg 			 null_result,
   1798  1.1  mrg 			 trans_os_error_at (NULL,
   1799  1.1  mrg 					    "Error reallocating to %lu bytes",
   1800  1.1  mrg 					    fold_convert
   1801  1.1  mrg 					    (long_unsigned_type_node, size)),
   1802  1.1  mrg 			 build_empty_stmt (input_location));
   1803  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1804  1.1  mrg 
   1805  1.1  mrg   return res;
   1806  1.1  mrg }
   1807  1.1  mrg 
   1808  1.1  mrg 
   1809  1.1  mrg /* Add an expression to another one, either at the front or the back.  */
   1810  1.1  mrg 
   1811  1.1  mrg static void
   1812  1.1  mrg add_expr_to_chain (tree* chain, tree expr, bool front)
   1813  1.1  mrg {
   1814  1.1  mrg   if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
   1815  1.1  mrg     return;
   1816  1.1  mrg 
   1817  1.1  mrg   if (*chain)
   1818  1.1  mrg     {
   1819  1.1  mrg       if (TREE_CODE (*chain) != STATEMENT_LIST)
   1820  1.1  mrg 	{
   1821  1.1  mrg 	  tree tmp;
   1822  1.1  mrg 
   1823  1.1  mrg 	  tmp = *chain;
   1824  1.1  mrg 	  *chain = NULL_TREE;
   1825  1.1  mrg 	  append_to_statement_list (tmp, chain);
   1826  1.1  mrg 	}
   1827  1.1  mrg 
   1828  1.1  mrg       if (front)
   1829  1.1  mrg 	{
   1830  1.1  mrg 	  tree_stmt_iterator i;
   1831  1.1  mrg 
   1832  1.1  mrg 	  i = tsi_start (*chain);
   1833  1.1  mrg 	  tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
   1834  1.1  mrg 	}
   1835  1.1  mrg       else
   1836  1.1  mrg 	append_to_statement_list (expr, chain);
   1837  1.1  mrg     }
   1838  1.1  mrg   else
   1839  1.1  mrg     *chain = expr;
   1840  1.1  mrg }
   1841  1.1  mrg 
   1842  1.1  mrg 
   1843  1.1  mrg /* Add a statement at the end of a block.  */
   1844  1.1  mrg 
   1845  1.1  mrg void
   1846  1.1  mrg gfc_add_expr_to_block (stmtblock_t * block, tree expr)
   1847  1.1  mrg {
   1848  1.1  mrg   gcc_assert (block);
   1849  1.1  mrg   add_expr_to_chain (&block->head, expr, false);
   1850  1.1  mrg }
   1851  1.1  mrg 
   1852  1.1  mrg 
   1853  1.1  mrg /* Add a statement at the beginning of a block.  */
   1854  1.1  mrg 
   1855  1.1  mrg void
   1856  1.1  mrg gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
   1857  1.1  mrg {
   1858  1.1  mrg   gcc_assert (block);
   1859  1.1  mrg   add_expr_to_chain (&block->head, expr, true);
   1860  1.1  mrg }
   1861  1.1  mrg 
   1862  1.1  mrg 
   1863  1.1  mrg /* Add a block the end of a block.  */
   1864  1.1  mrg 
   1865  1.1  mrg void
   1866  1.1  mrg gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
   1867  1.1  mrg {
   1868  1.1  mrg   gcc_assert (append);
   1869  1.1  mrg   gcc_assert (!append->has_scope);
   1870  1.1  mrg 
   1871  1.1  mrg   gfc_add_expr_to_block (block, append->head);
   1872  1.1  mrg   append->head = NULL_TREE;
   1873  1.1  mrg }
   1874  1.1  mrg 
   1875  1.1  mrg 
   1876  1.1  mrg /* Save the current locus.  The structure may not be complete, and should
   1877  1.1  mrg    only be used with gfc_restore_backend_locus.  */
   1878  1.1  mrg 
   1879  1.1  mrg void
   1880  1.1  mrg gfc_save_backend_locus (locus * loc)
   1881  1.1  mrg {
   1882  1.1  mrg   loc->lb = XCNEW (gfc_linebuf);
   1883  1.1  mrg   loc->lb->location = input_location;
   1884  1.1  mrg   loc->lb->file = gfc_current_backend_file;
   1885  1.1  mrg }
   1886  1.1  mrg 
   1887  1.1  mrg 
   1888  1.1  mrg /* Set the current locus.  */
   1889  1.1  mrg 
   1890  1.1  mrg void
   1891  1.1  mrg gfc_set_backend_locus (locus * loc)
   1892  1.1  mrg {
   1893  1.1  mrg   gfc_current_backend_file = loc->lb->file;
   1894  1.1  mrg   input_location = gfc_get_location (loc);
   1895  1.1  mrg }
   1896  1.1  mrg 
   1897  1.1  mrg 
   1898  1.1  mrg /* Restore the saved locus. Only used in conjunction with
   1899  1.1  mrg    gfc_save_backend_locus, to free the memory when we are done.  */
   1900  1.1  mrg 
   1901  1.1  mrg void
   1902  1.1  mrg gfc_restore_backend_locus (locus * loc)
   1903  1.1  mrg {
   1904  1.1  mrg   /* This only restores the information captured by gfc_save_backend_locus,
   1905  1.1  mrg      intentionally does not use gfc_get_location.  */
   1906  1.1  mrg   input_location = loc->lb->location;
   1907  1.1  mrg   gfc_current_backend_file = loc->lb->file;
   1908  1.1  mrg   free (loc->lb);
   1909  1.1  mrg }
   1910  1.1  mrg 
   1911  1.1  mrg 
   1912  1.1  mrg /* Translate an executable statement. The tree cond is used by gfc_trans_do.
   1913  1.1  mrg    This static function is wrapped by gfc_trans_code_cond and
   1914  1.1  mrg    gfc_trans_code.  */
   1915  1.1  mrg 
   1916  1.1  mrg static tree
   1917  1.1  mrg trans_code (gfc_code * code, tree cond)
   1918  1.1  mrg {
   1919  1.1  mrg   stmtblock_t block;
   1920  1.1  mrg   tree res;
   1921  1.1  mrg 
   1922  1.1  mrg   if (!code)
   1923  1.1  mrg     return build_empty_stmt (input_location);
   1924  1.1  mrg 
   1925  1.1  mrg   gfc_start_block (&block);
   1926  1.1  mrg 
   1927  1.1  mrg   /* Translate statements one by one into GENERIC trees until we reach
   1928  1.1  mrg      the end of this gfc_code branch.  */
   1929  1.1  mrg   for (; code; code = code->next)
   1930  1.1  mrg     {
   1931  1.1  mrg       if (code->here != 0)
   1932  1.1  mrg 	{
   1933  1.1  mrg 	  res = gfc_trans_label_here (code);
   1934  1.1  mrg 	  gfc_add_expr_to_block (&block, res);
   1935  1.1  mrg 	}
   1936  1.1  mrg 
   1937  1.1  mrg       gfc_current_locus = code->loc;
   1938  1.1  mrg       gfc_set_backend_locus (&code->loc);
   1939  1.1  mrg 
   1940  1.1  mrg       switch (code->op)
   1941  1.1  mrg 	{
   1942  1.1  mrg 	case EXEC_NOP:
   1943  1.1  mrg 	case EXEC_END_BLOCK:
   1944  1.1  mrg 	case EXEC_END_NESTED_BLOCK:
   1945  1.1  mrg 	case EXEC_END_PROCEDURE:
   1946  1.1  mrg 	  res = NULL_TREE;
   1947  1.1  mrg 	  break;
   1948  1.1  mrg 
   1949  1.1  mrg 	case EXEC_ASSIGN:
   1950  1.1  mrg 	  res = gfc_trans_assign (code);
   1951  1.1  mrg 	  break;
   1952  1.1  mrg 
   1953  1.1  mrg         case EXEC_LABEL_ASSIGN:
   1954  1.1  mrg           res = gfc_trans_label_assign (code);
   1955  1.1  mrg           break;
   1956  1.1  mrg 
   1957  1.1  mrg 	case EXEC_POINTER_ASSIGN:
   1958  1.1  mrg 	  res = gfc_trans_pointer_assign (code);
   1959  1.1  mrg 	  break;
   1960  1.1  mrg 
   1961  1.1  mrg 	case EXEC_INIT_ASSIGN:
   1962  1.1  mrg 	  if (code->expr1->ts.type == BT_CLASS)
   1963  1.1  mrg 	    res = gfc_trans_class_init_assign (code);
   1964  1.1  mrg 	  else
   1965  1.1  mrg 	    res = gfc_trans_init_assign (code);
   1966  1.1  mrg 	  break;
   1967  1.1  mrg 
   1968  1.1  mrg 	case EXEC_CONTINUE:
   1969  1.1  mrg 	  res = NULL_TREE;
   1970  1.1  mrg 	  break;
   1971  1.1  mrg 
   1972  1.1  mrg 	case EXEC_CRITICAL:
   1973  1.1  mrg 	  res = gfc_trans_critical (code);
   1974  1.1  mrg 	  break;
   1975  1.1  mrg 
   1976  1.1  mrg 	case EXEC_CYCLE:
   1977  1.1  mrg 	  res = gfc_trans_cycle (code);
   1978  1.1  mrg 	  break;
   1979  1.1  mrg 
   1980  1.1  mrg 	case EXEC_EXIT:
   1981  1.1  mrg 	  res = gfc_trans_exit (code);
   1982  1.1  mrg 	  break;
   1983  1.1  mrg 
   1984  1.1  mrg 	case EXEC_GOTO:
   1985  1.1  mrg 	  res = gfc_trans_goto (code);
   1986  1.1  mrg 	  break;
   1987  1.1  mrg 
   1988  1.1  mrg 	case EXEC_ENTRY:
   1989  1.1  mrg 	  res = gfc_trans_entry (code);
   1990  1.1  mrg 	  break;
   1991  1.1  mrg 
   1992  1.1  mrg 	case EXEC_PAUSE:
   1993  1.1  mrg 	  res = gfc_trans_pause (code);
   1994  1.1  mrg 	  break;
   1995  1.1  mrg 
   1996  1.1  mrg 	case EXEC_STOP:
   1997  1.1  mrg 	case EXEC_ERROR_STOP:
   1998  1.1  mrg 	  res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
   1999  1.1  mrg 	  break;
   2000  1.1  mrg 
   2001  1.1  mrg 	case EXEC_CALL:
   2002  1.1  mrg 	  /* For MVBITS we've got the special exception that we need a
   2003  1.1  mrg 	     dependency check, too.  */
   2004  1.1  mrg 	  {
   2005  1.1  mrg 	    bool is_mvbits = false;
   2006  1.1  mrg 
   2007  1.1  mrg 	    if (code->resolved_isym)
   2008  1.1  mrg 	      {
   2009  1.1  mrg 		res = gfc_conv_intrinsic_subroutine (code);
   2010  1.1  mrg 		if (res != NULL_TREE)
   2011  1.1  mrg 		  break;
   2012  1.1  mrg 	      }
   2013  1.1  mrg 
   2014  1.1  mrg 	    if (code->resolved_isym
   2015  1.1  mrg 		&& code->resolved_isym->id == GFC_ISYM_MVBITS)
   2016  1.1  mrg 	      is_mvbits = true;
   2017  1.1  mrg 
   2018  1.1  mrg 	    res = gfc_trans_call (code, is_mvbits, NULL_TREE,
   2019  1.1  mrg 				  NULL_TREE, false);
   2020  1.1  mrg 	  }
   2021  1.1  mrg 	  break;
   2022  1.1  mrg 
   2023  1.1  mrg 	case EXEC_CALL_PPC:
   2024  1.1  mrg 	  res = gfc_trans_call (code, false, NULL_TREE,
   2025  1.1  mrg 				NULL_TREE, false);
   2026  1.1  mrg 	  break;
   2027  1.1  mrg 
   2028  1.1  mrg 	case EXEC_ASSIGN_CALL:
   2029  1.1  mrg 	  res = gfc_trans_call (code, true, NULL_TREE,
   2030  1.1  mrg 				NULL_TREE, false);
   2031  1.1  mrg 	  break;
   2032  1.1  mrg 
   2033  1.1  mrg 	case EXEC_RETURN:
   2034  1.1  mrg 	  res = gfc_trans_return (code);
   2035  1.1  mrg 	  break;
   2036  1.1  mrg 
   2037  1.1  mrg 	case EXEC_IF:
   2038  1.1  mrg 	  res = gfc_trans_if (code);
   2039  1.1  mrg 	  break;
   2040  1.1  mrg 
   2041  1.1  mrg 	case EXEC_ARITHMETIC_IF:
   2042  1.1  mrg 	  res = gfc_trans_arithmetic_if (code);
   2043  1.1  mrg 	  break;
   2044  1.1  mrg 
   2045  1.1  mrg 	case EXEC_BLOCK:
   2046  1.1  mrg 	  res = gfc_trans_block_construct (code);
   2047  1.1  mrg 	  break;
   2048  1.1  mrg 
   2049  1.1  mrg 	case EXEC_DO:
   2050  1.1  mrg 	  res = gfc_trans_do (code, cond);
   2051  1.1  mrg 	  break;
   2052  1.1  mrg 
   2053  1.1  mrg 	case EXEC_DO_CONCURRENT:
   2054  1.1  mrg 	  res = gfc_trans_do_concurrent (code);
   2055  1.1  mrg 	  break;
   2056  1.1  mrg 
   2057  1.1  mrg 	case EXEC_DO_WHILE:
   2058  1.1  mrg 	  res = gfc_trans_do_while (code);
   2059  1.1  mrg 	  break;
   2060  1.1  mrg 
   2061  1.1  mrg 	case EXEC_SELECT:
   2062  1.1  mrg 	  res = gfc_trans_select (code);
   2063  1.1  mrg 	  break;
   2064  1.1  mrg 
   2065  1.1  mrg 	case EXEC_SELECT_TYPE:
   2066  1.1  mrg 	  res = gfc_trans_select_type (code);
   2067  1.1  mrg 	  break;
   2068  1.1  mrg 
   2069  1.1  mrg 	case EXEC_SELECT_RANK:
   2070  1.1  mrg 	  res = gfc_trans_select_rank (code);
   2071  1.1  mrg 	  break;
   2072  1.1  mrg 
   2073  1.1  mrg 	case EXEC_FLUSH:
   2074  1.1  mrg 	  res = gfc_trans_flush (code);
   2075  1.1  mrg 	  break;
   2076  1.1  mrg 
   2077  1.1  mrg 	case EXEC_SYNC_ALL:
   2078  1.1  mrg 	case EXEC_SYNC_IMAGES:
   2079  1.1  mrg 	case EXEC_SYNC_MEMORY:
   2080  1.1  mrg 	  res = gfc_trans_sync (code, code->op);
   2081  1.1  mrg 	  break;
   2082  1.1  mrg 
   2083  1.1  mrg 	case EXEC_LOCK:
   2084  1.1  mrg 	case EXEC_UNLOCK:
   2085  1.1  mrg 	  res = gfc_trans_lock_unlock (code, code->op);
   2086  1.1  mrg 	  break;
   2087  1.1  mrg 
   2088  1.1  mrg 	case EXEC_EVENT_POST:
   2089  1.1  mrg 	case EXEC_EVENT_WAIT:
   2090  1.1  mrg 	  res = gfc_trans_event_post_wait (code, code->op);
   2091  1.1  mrg 	  break;
   2092  1.1  mrg 
   2093  1.1  mrg 	case EXEC_FAIL_IMAGE:
   2094  1.1  mrg 	  res = gfc_trans_fail_image (code);
   2095  1.1  mrg 	  break;
   2096  1.1  mrg 
   2097  1.1  mrg 	case EXEC_FORALL:
   2098  1.1  mrg 	  res = gfc_trans_forall (code);
   2099  1.1  mrg 	  break;
   2100  1.1  mrg 
   2101  1.1  mrg 	case EXEC_FORM_TEAM:
   2102  1.1  mrg 	  res = gfc_trans_form_team (code);
   2103  1.1  mrg 	  break;
   2104  1.1  mrg 
   2105  1.1  mrg 	case EXEC_CHANGE_TEAM:
   2106  1.1  mrg 	  res = gfc_trans_change_team (code);
   2107  1.1  mrg 	  break;
   2108  1.1  mrg 
   2109  1.1  mrg 	case EXEC_END_TEAM:
   2110  1.1  mrg 	  res = gfc_trans_end_team (code);
   2111  1.1  mrg 	  break;
   2112  1.1  mrg 
   2113  1.1  mrg 	case EXEC_SYNC_TEAM:
   2114  1.1  mrg 	  res = gfc_trans_sync_team (code);
   2115  1.1  mrg 	  break;
   2116  1.1  mrg 
   2117  1.1  mrg 	case EXEC_WHERE:
   2118  1.1  mrg 	  res = gfc_trans_where (code);
   2119  1.1  mrg 	  break;
   2120  1.1  mrg 
   2121  1.1  mrg 	case EXEC_ALLOCATE:
   2122  1.1  mrg 	  res = gfc_trans_allocate (code);
   2123  1.1  mrg 	  break;
   2124  1.1  mrg 
   2125  1.1  mrg 	case EXEC_DEALLOCATE:
   2126  1.1  mrg 	  res = gfc_trans_deallocate (code);
   2127  1.1  mrg 	  break;
   2128  1.1  mrg 
   2129  1.1  mrg 	case EXEC_OPEN:
   2130  1.1  mrg 	  res = gfc_trans_open (code);
   2131  1.1  mrg 	  break;
   2132  1.1  mrg 
   2133  1.1  mrg 	case EXEC_CLOSE:
   2134  1.1  mrg 	  res = gfc_trans_close (code);
   2135  1.1  mrg 	  break;
   2136  1.1  mrg 
   2137  1.1  mrg 	case EXEC_READ:
   2138  1.1  mrg 	  res = gfc_trans_read (code);
   2139  1.1  mrg 	  break;
   2140  1.1  mrg 
   2141  1.1  mrg 	case EXEC_WRITE:
   2142  1.1  mrg 	  res = gfc_trans_write (code);
   2143  1.1  mrg 	  break;
   2144  1.1  mrg 
   2145  1.1  mrg 	case EXEC_IOLENGTH:
   2146  1.1  mrg 	  res = gfc_trans_iolength (code);
   2147  1.1  mrg 	  break;
   2148  1.1  mrg 
   2149  1.1  mrg 	case EXEC_BACKSPACE:
   2150  1.1  mrg 	  res = gfc_trans_backspace (code);
   2151  1.1  mrg 	  break;
   2152  1.1  mrg 
   2153  1.1  mrg 	case EXEC_ENDFILE:
   2154  1.1  mrg 	  res = gfc_trans_endfile (code);
   2155  1.1  mrg 	  break;
   2156  1.1  mrg 
   2157  1.1  mrg 	case EXEC_INQUIRE:
   2158  1.1  mrg 	  res = gfc_trans_inquire (code);
   2159  1.1  mrg 	  break;
   2160  1.1  mrg 
   2161  1.1  mrg 	case EXEC_WAIT:
   2162  1.1  mrg 	  res = gfc_trans_wait (code);
   2163  1.1  mrg 	  break;
   2164  1.1  mrg 
   2165  1.1  mrg 	case EXEC_REWIND:
   2166  1.1  mrg 	  res = gfc_trans_rewind (code);
   2167  1.1  mrg 	  break;
   2168  1.1  mrg 
   2169  1.1  mrg 	case EXEC_TRANSFER:
   2170  1.1  mrg 	  res = gfc_trans_transfer (code);
   2171  1.1  mrg 	  break;
   2172  1.1  mrg 
   2173  1.1  mrg 	case EXEC_DT_END:
   2174  1.1  mrg 	  res = gfc_trans_dt_end (code);
   2175  1.1  mrg 	  break;
   2176  1.1  mrg 
   2177  1.1  mrg 	case EXEC_OMP_ATOMIC:
   2178  1.1  mrg 	case EXEC_OMP_BARRIER:
   2179  1.1  mrg 	case EXEC_OMP_CANCEL:
   2180  1.1  mrg 	case EXEC_OMP_CANCELLATION_POINT:
   2181  1.1  mrg 	case EXEC_OMP_CRITICAL:
   2182  1.1  mrg 	case EXEC_OMP_DEPOBJ:
   2183  1.1  mrg 	case EXEC_OMP_DISTRIBUTE:
   2184  1.1  mrg 	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
   2185  1.1  mrg 	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
   2186  1.1  mrg 	case EXEC_OMP_DISTRIBUTE_SIMD:
   2187  1.1  mrg 	case EXEC_OMP_DO:
   2188  1.1  mrg 	case EXEC_OMP_DO_SIMD:
   2189  1.1  mrg 	case EXEC_OMP_LOOP:
   2190  1.1  mrg 	case EXEC_OMP_ERROR:
   2191  1.1  mrg 	case EXEC_OMP_FLUSH:
   2192  1.1  mrg 	case EXEC_OMP_MASKED:
   2193  1.1  mrg 	case EXEC_OMP_MASKED_TASKLOOP:
   2194  1.1  mrg 	case EXEC_OMP_MASKED_TASKLOOP_SIMD:
   2195  1.1  mrg 	case EXEC_OMP_MASTER:
   2196  1.1  mrg 	case EXEC_OMP_MASTER_TASKLOOP:
   2197  1.1  mrg 	case EXEC_OMP_MASTER_TASKLOOP_SIMD:
   2198  1.1  mrg 	case EXEC_OMP_ORDERED:
   2199  1.1  mrg 	case EXEC_OMP_PARALLEL:
   2200  1.1  mrg 	case EXEC_OMP_PARALLEL_DO:
   2201  1.1  mrg 	case EXEC_OMP_PARALLEL_DO_SIMD:
   2202  1.1  mrg 	case EXEC_OMP_PARALLEL_LOOP:
   2203  1.1  mrg 	case EXEC_OMP_PARALLEL_MASKED:
   2204  1.1  mrg 	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
   2205  1.1  mrg 	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
   2206  1.1  mrg 	case EXEC_OMP_PARALLEL_MASTER:
   2207  1.1  mrg 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
   2208  1.1  mrg 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
   2209  1.1  mrg 	case EXEC_OMP_PARALLEL_SECTIONS:
   2210  1.1  mrg 	case EXEC_OMP_PARALLEL_WORKSHARE:
   2211  1.1  mrg 	case EXEC_OMP_SCOPE:
   2212  1.1  mrg 	case EXEC_OMP_SECTIONS:
   2213  1.1  mrg 	case EXEC_OMP_SIMD:
   2214  1.1  mrg 	case EXEC_OMP_SINGLE:
   2215  1.1  mrg 	case EXEC_OMP_TARGET:
   2216  1.1  mrg 	case EXEC_OMP_TARGET_DATA:
   2217  1.1  mrg 	case EXEC_OMP_TARGET_ENTER_DATA:
   2218  1.1  mrg 	case EXEC_OMP_TARGET_EXIT_DATA:
   2219  1.1  mrg 	case EXEC_OMP_TARGET_PARALLEL:
   2220  1.1  mrg 	case EXEC_OMP_TARGET_PARALLEL_DO:
   2221  1.1  mrg 	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
   2222  1.1  mrg 	case EXEC_OMP_TARGET_PARALLEL_LOOP:
   2223  1.1  mrg 	case EXEC_OMP_TARGET_SIMD:
   2224  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS:
   2225  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
   2226  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
   2227  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
   2228  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
   2229  1.1  mrg 	case EXEC_OMP_TARGET_TEAMS_LOOP:
   2230  1.1  mrg 	case EXEC_OMP_TARGET_UPDATE:
   2231  1.1  mrg 	case EXEC_OMP_TASK:
   2232  1.1  mrg 	case EXEC_OMP_TASKGROUP:
   2233  1.1  mrg 	case EXEC_OMP_TASKLOOP:
   2234  1.1  mrg 	case EXEC_OMP_TASKLOOP_SIMD:
   2235  1.1  mrg 	case EXEC_OMP_TASKWAIT:
   2236  1.1  mrg 	case EXEC_OMP_TASKYIELD:
   2237  1.1  mrg 	case EXEC_OMP_TEAMS:
   2238  1.1  mrg 	case EXEC_OMP_TEAMS_DISTRIBUTE:
   2239  1.1  mrg 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
   2240  1.1  mrg 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
   2241  1.1  mrg 	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
   2242  1.1  mrg 	case EXEC_OMP_TEAMS_LOOP:
   2243  1.1  mrg 	case EXEC_OMP_WORKSHARE:
   2244  1.1  mrg 	  res = gfc_trans_omp_directive (code);
   2245  1.1  mrg 	  break;
   2246  1.1  mrg 
   2247  1.1  mrg 	case EXEC_OACC_CACHE:
   2248  1.1  mrg 	case EXEC_OACC_WAIT:
   2249  1.1  mrg 	case EXEC_OACC_UPDATE:
   2250  1.1  mrg 	case EXEC_OACC_LOOP:
   2251  1.1  mrg 	case EXEC_OACC_HOST_DATA:
   2252  1.1  mrg 	case EXEC_OACC_DATA:
   2253  1.1  mrg 	case EXEC_OACC_KERNELS:
   2254  1.1  mrg 	case EXEC_OACC_KERNELS_LOOP:
   2255  1.1  mrg 	case EXEC_OACC_PARALLEL:
   2256  1.1  mrg 	case EXEC_OACC_PARALLEL_LOOP:
   2257  1.1  mrg 	case EXEC_OACC_SERIAL:
   2258  1.1  mrg 	case EXEC_OACC_SERIAL_LOOP:
   2259  1.1  mrg 	case EXEC_OACC_ENTER_DATA:
   2260  1.1  mrg 	case EXEC_OACC_EXIT_DATA:
   2261  1.1  mrg 	case EXEC_OACC_ATOMIC:
   2262  1.1  mrg 	case EXEC_OACC_DECLARE:
   2263  1.1  mrg 	  res = gfc_trans_oacc_directive (code);
   2264  1.1  mrg 	  break;
   2265  1.1  mrg 
   2266  1.1  mrg 	default:
   2267  1.1  mrg 	  gfc_internal_error ("gfc_trans_code(): Bad statement code");
   2268  1.1  mrg 	}
   2269  1.1  mrg 
   2270  1.1  mrg       gfc_set_backend_locus (&code->loc);
   2271  1.1  mrg 
   2272  1.1  mrg       if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
   2273  1.1  mrg 	{
   2274  1.1  mrg 	  if (TREE_CODE (res) != STATEMENT_LIST)
   2275  1.1  mrg 	    SET_EXPR_LOCATION (res, input_location);
   2276  1.1  mrg 
   2277  1.1  mrg 	  /* Add the new statement to the block.  */
   2278  1.1  mrg 	  gfc_add_expr_to_block (&block, res);
   2279  1.1  mrg 	}
   2280  1.1  mrg     }
   2281  1.1  mrg 
   2282  1.1  mrg   /* Return the finished block.  */
   2283  1.1  mrg   return gfc_finish_block (&block);
   2284  1.1  mrg }
   2285  1.1  mrg 
   2286  1.1  mrg 
   2287  1.1  mrg /* Translate an executable statement with condition, cond.  The condition is
   2288  1.1  mrg    used by gfc_trans_do to test for IO result conditions inside implied
   2289  1.1  mrg    DO loops of READ and WRITE statements.  See build_dt in trans-io.cc.  */
   2290  1.1  mrg 
   2291  1.1  mrg tree
   2292  1.1  mrg gfc_trans_code_cond (gfc_code * code, tree cond)
   2293  1.1  mrg {
   2294  1.1  mrg   return trans_code (code, cond);
   2295  1.1  mrg }
   2296  1.1  mrg 
   2297  1.1  mrg /* Translate an executable statement without condition.  */
   2298  1.1  mrg 
   2299  1.1  mrg tree
   2300  1.1  mrg gfc_trans_code (gfc_code * code)
   2301  1.1  mrg {
   2302  1.1  mrg   return trans_code (code, NULL_TREE);
   2303  1.1  mrg }
   2304  1.1  mrg 
   2305  1.1  mrg 
   2306  1.1  mrg /* This function is called after a complete program unit has been parsed
   2307  1.1  mrg    and resolved.  */
   2308  1.1  mrg 
   2309  1.1  mrg void
   2310  1.1  mrg gfc_generate_code (gfc_namespace * ns)
   2311  1.1  mrg {
   2312  1.1  mrg   ompws_flags = 0;
   2313  1.1  mrg   if (ns->is_block_data)
   2314  1.1  mrg     {
   2315  1.1  mrg       gfc_generate_block_data (ns);
   2316  1.1  mrg       return;
   2317  1.1  mrg     }
   2318  1.1  mrg 
   2319  1.1  mrg   gfc_generate_function_code (ns);
   2320  1.1  mrg }
   2321  1.1  mrg 
   2322  1.1  mrg 
   2323  1.1  mrg /* This function is called after a complete module has been parsed
   2324  1.1  mrg    and resolved.  */
   2325  1.1  mrg 
   2326  1.1  mrg void
   2327  1.1  mrg gfc_generate_module_code (gfc_namespace * ns)
   2328  1.1  mrg {
   2329  1.1  mrg   gfc_namespace *n;
   2330  1.1  mrg   struct module_htab_entry *entry;
   2331  1.1  mrg 
   2332  1.1  mrg   gcc_assert (ns->proc_name->backend_decl == NULL);
   2333  1.1  mrg   ns->proc_name->backend_decl
   2334  1.1  mrg     = build_decl (gfc_get_location (&ns->proc_name->declared_at),
   2335  1.1  mrg 		  NAMESPACE_DECL, get_identifier (ns->proc_name->name),
   2336  1.1  mrg 		  void_type_node);
   2337  1.1  mrg   entry = gfc_find_module (ns->proc_name->name);
   2338  1.1  mrg   if (entry->namespace_decl)
   2339  1.1  mrg     /* Buggy sourcecode, using a module before defining it?  */
   2340  1.1  mrg     entry->decls->empty ();
   2341  1.1  mrg   entry->namespace_decl = ns->proc_name->backend_decl;
   2342  1.1  mrg 
   2343  1.1  mrg   gfc_generate_module_vars (ns);
   2344  1.1  mrg 
   2345  1.1  mrg   /* We need to generate all module function prototypes first, to allow
   2346  1.1  mrg      sibling calls.  */
   2347  1.1  mrg   for (n = ns->contained; n; n = n->sibling)
   2348  1.1  mrg     {
   2349  1.1  mrg       gfc_entry_list *el;
   2350  1.1  mrg 
   2351  1.1  mrg       if (!n->proc_name)
   2352  1.1  mrg         continue;
   2353  1.1  mrg 
   2354  1.1  mrg       gfc_create_function_decl (n, false);
   2355  1.1  mrg       DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
   2356  1.1  mrg       gfc_module_add_decl (entry, n->proc_name->backend_decl);
   2357  1.1  mrg       for (el = ns->entries; el; el = el->next)
   2358  1.1  mrg 	{
   2359  1.1  mrg 	  DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
   2360  1.1  mrg 	  gfc_module_add_decl (entry, el->sym->backend_decl);
   2361  1.1  mrg 	}
   2362  1.1  mrg     }
   2363  1.1  mrg 
   2364  1.1  mrg   for (n = ns->contained; n; n = n->sibling)
   2365  1.1  mrg     {
   2366  1.1  mrg       if (!n->proc_name)
   2367  1.1  mrg         continue;
   2368  1.1  mrg 
   2369  1.1  mrg       gfc_generate_function_code (n);
   2370  1.1  mrg     }
   2371  1.1  mrg }
   2372  1.1  mrg 
   2373  1.1  mrg 
   2374  1.1  mrg /* Initialize an init/cleanup block with existing code.  */
   2375  1.1  mrg 
   2376  1.1  mrg void
   2377  1.1  mrg gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
   2378  1.1  mrg {
   2379  1.1  mrg   gcc_assert (block);
   2380  1.1  mrg 
   2381  1.1  mrg   block->init = NULL_TREE;
   2382  1.1  mrg   block->code = code;
   2383  1.1  mrg   block->cleanup = NULL_TREE;
   2384  1.1  mrg }
   2385  1.1  mrg 
   2386  1.1  mrg 
   2387  1.1  mrg /* Add a new pair of initializers/clean-up code.  */
   2388  1.1  mrg 
   2389  1.1  mrg void
   2390  1.1  mrg gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
   2391  1.1  mrg {
   2392  1.1  mrg   gcc_assert (block);
   2393  1.1  mrg 
   2394  1.1  mrg   /* The new pair of init/cleanup should be "wrapped around" the existing
   2395  1.1  mrg      block of code, thus the initialization is added to the front and the
   2396  1.1  mrg      cleanup to the back.  */
   2397  1.1  mrg   add_expr_to_chain (&block->init, init, true);
   2398  1.1  mrg   add_expr_to_chain (&block->cleanup, cleanup, false);
   2399  1.1  mrg }
   2400  1.1  mrg 
   2401  1.1  mrg 
   2402  1.1  mrg /* Finish up a wrapped block by building a corresponding try-finally expr.  */
   2403  1.1  mrg 
   2404  1.1  mrg tree
   2405  1.1  mrg gfc_finish_wrapped_block (gfc_wrapped_block* block)
   2406  1.1  mrg {
   2407  1.1  mrg   tree result;
   2408  1.1  mrg 
   2409  1.1  mrg   gcc_assert (block);
   2410  1.1  mrg 
   2411  1.1  mrg   /* Build the final expression.  For this, just add init and body together,
   2412  1.1  mrg      and put clean-up with that into a TRY_FINALLY_EXPR.  */
   2413  1.1  mrg   result = block->init;
   2414  1.1  mrg   add_expr_to_chain (&result, block->code, false);
   2415  1.1  mrg   if (block->cleanup)
   2416  1.1  mrg     result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
   2417  1.1  mrg 			 result, block->cleanup);
   2418  1.1  mrg 
   2419  1.1  mrg   /* Clear the block.  */
   2420  1.1  mrg   block->init = NULL_TREE;
   2421  1.1  mrg   block->code = NULL_TREE;
   2422  1.1  mrg   block->cleanup = NULL_TREE;
   2423  1.1  mrg 
   2424  1.1  mrg   return result;
   2425  1.1  mrg }
   2426  1.1  mrg 
   2427  1.1  mrg 
   2428  1.1  mrg /* Helper function for marking a boolean expression tree as unlikely.  */
   2429  1.1  mrg 
   2430  1.1  mrg tree
   2431  1.1  mrg gfc_unlikely (tree cond, enum br_predictor predictor)
   2432  1.1  mrg {
   2433  1.1  mrg   tree tmp;
   2434  1.1  mrg 
   2435  1.1  mrg   if (optimize)
   2436  1.1  mrg     {
   2437  1.1  mrg       cond = fold_convert (long_integer_type_node, cond);
   2438  1.1  mrg       tmp = build_zero_cst (long_integer_type_node);
   2439  1.1  mrg       cond = build_call_expr_loc (input_location,
   2440  1.1  mrg 				  builtin_decl_explicit (BUILT_IN_EXPECT),
   2441  1.1  mrg 				  3, cond, tmp,
   2442  1.1  mrg 				  build_int_cst (integer_type_node,
   2443  1.1  mrg 						 predictor));
   2444  1.1  mrg     }
   2445  1.1  mrg   return cond;
   2446  1.1  mrg }
   2447  1.1  mrg 
   2448  1.1  mrg 
   2449  1.1  mrg /* Helper function for marking a boolean expression tree as likely.  */
   2450  1.1  mrg 
   2451  1.1  mrg tree
   2452  1.1  mrg gfc_likely (tree cond, enum br_predictor predictor)
   2453  1.1  mrg {
   2454  1.1  mrg   tree tmp;
   2455  1.1  mrg 
   2456  1.1  mrg   if (optimize)
   2457  1.1  mrg     {
   2458  1.1  mrg       cond = fold_convert (long_integer_type_node, cond);
   2459  1.1  mrg       tmp = build_one_cst (long_integer_type_node);
   2460  1.1  mrg       cond = build_call_expr_loc (input_location,
   2461  1.1  mrg 				  builtin_decl_explicit (BUILT_IN_EXPECT),
   2462  1.1  mrg 				  3, cond, tmp,
   2463  1.1  mrg 				  build_int_cst (integer_type_node,
   2464  1.1  mrg 						 predictor));
   2465  1.1  mrg     }
   2466  1.1  mrg   return cond;
   2467  1.1  mrg }
   2468  1.1  mrg 
   2469  1.1  mrg 
   2470  1.1  mrg /* Get the string length for a deferred character length component.  */
   2471  1.1  mrg 
   2472  1.1  mrg bool
   2473  1.1  mrg gfc_deferred_strlen (gfc_component *c, tree *decl)
   2474  1.1  mrg {
   2475  1.1  mrg   char name[GFC_MAX_SYMBOL_LEN+9];
   2476  1.1  mrg   gfc_component *strlen;
   2477  1.1  mrg   if (!(c->ts.type == BT_CHARACTER
   2478  1.1  mrg 	&& (c->ts.deferred || c->attr.pdt_string)))
   2479  1.1  mrg     return false;
   2480  1.1  mrg   sprintf (name, "_%s_length", c->name);
   2481  1.1  mrg   for (strlen = c; strlen; strlen = strlen->next)
   2482  1.1  mrg     if (strcmp (strlen->name, name) == 0)
   2483  1.1  mrg       break;
   2484  1.1  mrg   *decl = strlen ? strlen->backend_decl : NULL_TREE;
   2485  1.1  mrg   return strlen != NULL;
   2486  1.1  mrg }
   2487