LCOV - code coverage report
Current view: top level - gcc/fortran - class.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.8 % 1807 1767
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 38 38
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Implementation of Fortran 2003 Polymorphism.
       2              :    Copyright (C) 2009-2026 Free Software Foundation, Inc.
       3              :    Contributed by Paul Richard Thomas <pault@gcc.gnu.org>
       4              :    and Janus Weil <janus@gcc.gnu.org>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : 
      23              : /* class.cc -- This file contains the front end functions needed to service
      24              :               the implementation of Fortran 2003 polymorphism and other
      25              :               object-oriented features.  */
      26              : 
      27              : 
      28              : /* Outline of the internal representation:
      29              : 
      30              :    Each CLASS variable is encapsulated by a class container, which is a
      31              :    structure with two fields:
      32              :     * _data: A pointer to the actual data of the variable. This field has the
      33              :              declared type of the class variable and its attributes
      34              :              (pointer/allocatable/dimension/...).
      35              :     * _vptr: A pointer to the vtable entry (see below) of the dynamic type.
      36              : 
      37              :     Only for unlimited polymorphic classes:
      38              :     * _len:  An integer(C_SIZE_T) to store the string length when the unlimited
      39              :              polymorphic pointer is used to point to a char array.  The '_len'
      40              :              component will be zero when no character array is stored in
      41              :              '_data'.
      42              : 
      43              :    For each derived type we set up a "vtable" entry, i.e. a structure with the
      44              :    following fields:
      45              :     * _hash:     A hash value serving as a unique identifier for this type.
      46              :     * _size:     The size in bytes of the derived type.
      47              :     * _extends:  A pointer to the vtable entry of the parent derived type.
      48              :     * _def_init: A pointer to a default initialized variable of this type.
      49              :     * _copy:     A procedure pointer to a copying procedure.
      50              :     * _final:    A procedure pointer to a wrapper function, which frees
      51              :                  allocatable components and calls FINAL subroutines.
      52              :     * _deallocate: A procedure pointer to a deallocation procedure; nonnull
      53              :                  only for a recursive derived type.
      54              : 
      55              :    After these follow procedure pointer components for the specific
      56              :    type-bound procedures.  */
      57              : 
      58              : 
      59              : #include "config.h"
      60              : #include "system.h"
      61              : #include "coretypes.h"
      62              : #include "gfortran.h"
      63              : #include "constructor.h"
      64              : #include "target-memory.h"
      65              : 
      66              : /* Inserts a derived type component reference in a data reference chain.
      67              :     TS: base type of the ref chain so far, in which we will pick the component
      68              :     REF: the address of the GFC_REF pointer to update
      69              :     NAME: name of the component to insert
      70              :    Note that component insertion makes sense only if we are at the end of
      71              :    the chain (*REF == NULL) or if we are adding a missing "_data" component
      72              :    to access the actual contents of a class object.  */
      73              : 
      74              : static void
      75        11385 : insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
      76              : {
      77        11385 :   gfc_ref *new_ref;
      78        11385 :   int wcnt, ecnt;
      79              : 
      80        11385 :   gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
      81              : 
      82        11385 :   gfc_find_component (ts->u.derived, name, true, true, &new_ref);
      83              : 
      84        11385 :   gfc_get_errors (&wcnt, &ecnt);
      85        11385 :   if (ecnt > 0 && !new_ref)
      86            1 :     return;
      87        11384 :   gcc_assert (new_ref->u.c.component);
      88              : 
      89        11384 :   while (new_ref->next)
      90            0 :     new_ref = new_ref->next;
      91        11384 :   new_ref->next = *ref;
      92              : 
      93        11384 :   if (new_ref->next)
      94              :     {
      95        11384 :       gfc_ref *next = NULL;
      96              : 
      97              :       /* We need to update the base type in the trailing reference chain to
      98              :          that of the new component.  */
      99              : 
     100        11384 :       gcc_assert (strcmp (name, "_data") == 0);
     101              : 
     102        11384 :       if (new_ref->next->type == REF_COMPONENT)
     103              :         next = new_ref->next;
     104        10855 :       else if (new_ref->next->type == REF_ARRAY
     105        10855 :                && new_ref->next->next
     106         2136 :                && new_ref->next->next->type == REF_COMPONENT)
     107              :         next = new_ref->next->next;
     108              : 
     109         2596 :       if (next != NULL)
     110              :         {
     111         2596 :           gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
     112              :                       || new_ref->u.c.component->ts.type == BT_DERIVED);
     113         2596 :           next->u.c.sym = new_ref->u.c.component->ts.u.derived;
     114              :         }
     115              :     }
     116              : 
     117        11384 :   *ref = new_ref;
     118              : }
     119              : 
     120              : 
     121              : /* Tells whether we need to add a "_data" reference to access REF subobject
     122              :    from an object of type TS.  If FIRST_REF_IN_CHAIN is set, then the base
     123              :    object accessed by REF is a variable; in other words it is a full object,
     124              :    not a subobject.  */
     125              : 
     126              : static bool
     127      1351345 : class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
     128              : {
     129              :   /* Only class containers may need the "_data" reference.  */
     130      1351345 :   if (ts->type != BT_CLASS)
     131              :     return false;
     132              : 
     133              :   /* Accessing a class container with an array reference is certainly wrong.  */
     134       110623 :   if (ref->type != REF_COMPONENT)
     135              :     return true;
     136              : 
     137              :   /* Accessing the class container's fields is fine.  */
     138        99767 :   if (ref->u.c.component->name[0] == '_')
     139              :     return false;
     140              : 
     141              :   /* At this point we have a class container with a non class container's field
     142              :      component reference.  We don't want to add the "_data" component if we are
     143              :      at the first reference and the symbol's type is an extended derived type.
     144              :      In that case, conv_parent_component_references will do the right thing so
     145              :      it is not absolutely necessary.  Omitting it prevents a regression (see
     146              :      class_41.f03) in the interface mapping mechanism.  When evaluating string
     147              :      lengths depending on dummy arguments, we create a fake symbol with a type
     148              :      equal to that of the dummy type.  However, because of type extension,
     149              :      the backend type (corresponding to the actual argument) can have a
     150              :      different (extended) type.  Adding the "_data" component explicitly, using
     151              :      the base type, confuses the gfc_conv_component_ref code which deals with
     152              :      the extended type.  */
     153        14799 :   if (first_ref_in_chain && ts->u.derived->attr.extension)
     154        14270 :     return false;
     155              : 
     156              :   /* We have a class container with a non class container's field component
     157              :      reference that doesn't fall into the above.  */
     158              :   return true;
     159              : }
     160              : 
     161              : 
     162              : /* Browse through a data reference chain and add the missing "_data" references
     163              :    when a subobject of a class object is accessed without it.
     164              :    Note that it doesn't add the "_data" reference when the class container
     165              :    is the last element in the reference chain.  */
     166              : 
     167              : void
     168      4548019 : gfc_fix_class_refs (gfc_expr *e)
     169              : {
     170      4548019 :   gfc_typespec *ts;
     171      4548019 :   gfc_ref **ref;
     172              : 
     173      4548019 :   if ((e->expr_type != EXPR_VARIABLE
     174      1982771 :        && e->expr_type != EXPR_FUNCTION)
     175      2865961 :       || (e->expr_type == EXPR_FUNCTION
     176       300713 :           && e->value.function.isym != NULL))
     177              :     return;
     178              : 
     179      2614801 :   if (e->expr_type == EXPR_VARIABLE)
     180      2565248 :     ts = &e->symtree->n.sym->ts;
     181              :   else
     182              :     {
     183        49553 :       gfc_symbol *func;
     184              : 
     185        49553 :       gcc_assert (e->expr_type == EXPR_FUNCTION);
     186        49553 :       if (e->value.function.esym != NULL)
     187              :         func = e->value.function.esym;
     188              :       else
     189         1614 :         func = e->symtree->n.sym;
     190              : 
     191        49553 :       if (func->result != NULL)
     192        48251 :         ts = &func->result->ts;
     193              :       else
     194         1302 :         ts = &func->ts;
     195              :     }
     196              : 
     197      3966146 :   for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
     198              :     {
     199      1351345 :       if (class_data_ref_missing (ts, *ref, ref == &e->ref))
     200        11385 :         insert_component_ref (ts, ref, "_data");
     201              : 
     202      1351345 :       if ((*ref)->type == REF_COMPONENT)
     203       281760 :         ts = &(*ref)->u.c.component->ts;
     204              :     }
     205              : }
     206              : 
     207              : 
     208              : /* Insert a reference to the component of the given name.
     209              :    Only to be used with CLASS containers and vtables.  */
     210              : 
     211              : void
     212        59472 : gfc_add_component_ref (gfc_expr *e, const char *name)
     213              : {
     214        59472 :   gfc_component *c;
     215        59472 :   gfc_ref **tail = &(e->ref);
     216        59472 :   gfc_ref *ref, *next = NULL;
     217        59472 :   gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
     218        84879 :   while (*tail != NULL)
     219              :     {
     220        40183 :       if ((*tail)->type == REF_COMPONENT)
     221              :         {
     222        24414 :           if (strcmp ((*tail)->u.c.component->name, "_data") == 0
     223         1411 :                 && (*tail)->next
     224         1411 :                 && (*tail)->next->type == REF_ARRAY
     225         1327 :                 && (*tail)->next->next == NULL)
     226              :             return;
     227        23345 :           derived = (*tail)->u.c.component->ts.u.derived;
     228              :         }
     229        39114 :       if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
     230              :         break;
     231        25407 :       tail = &((*tail)->next);
     232              :     }
     233        58403 :   if (derived && derived->components && derived->components->next &&
     234        58396 :       derived->components->next->ts.type == BT_DERIVED &&
     235        45188 :       derived->components->next->ts.u.derived == NULL)
     236              :     {
     237              :       /* Fix up missing vtype.  */
     238           19 :       gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
     239           19 :       gcc_assert (vtab);
     240           19 :       derived->components->next->ts.u.derived = vtab->ts.u.derived;
     241              :     }
     242        58403 :   if (*tail != NULL && strcmp (name, "_data") == 0)
     243              :     next = *tail;
     244              :   else
     245              :     /* Avoid losing memory.  */
     246        50504 :     gfc_free_ref_list (*tail);
     247        58403 :   c = gfc_find_component (derived, name, true, true, tail);
     248              : 
     249        58403 :   if (c) {
     250        58395 :     for (ref = *tail; ref->next; ref = ref->next)
     251              :       ;
     252        58395 :     ref->next = next;
     253        58395 :     if (!next)
     254        50496 :       e->ts = c->ts;
     255              :   }
     256              : }
     257              : 
     258              : 
     259              : /* This is used to add both the _data component reference and an array
     260              :    reference to class expressions.  Used in translation of intrinsic
     261              :    array inquiry functions.  */
     262              : 
     263              : void
     264         4915 : gfc_add_class_array_ref (gfc_expr *e)
     265              : {
     266         4915 :   int rank = CLASS_DATA (e)->as->rank;
     267         4915 :   int corank = CLASS_DATA (e)->as->corank;
     268         4915 :   gfc_array_spec *as = CLASS_DATA (e)->as;
     269         4915 :   gfc_ref *ref = NULL;
     270         4915 :   gfc_add_data_component (e);
     271         4915 :   e->rank = rank;
     272         4915 :   e->corank = corank;
     273         9388 :   for (ref = e->ref; ref; ref = ref->next)
     274         9387 :     if (!ref->next)
     275              :       break;
     276         4915 :   if (ref && ref->type != REF_ARRAY)
     277              :     {
     278         1160 :       ref->next = gfc_get_ref ();
     279         1160 :       ref = ref->next;
     280         1160 :       ref->type = REF_ARRAY;
     281         1160 :       ref->u.ar.type = AR_FULL;
     282         1160 :       ref->u.ar.as = as;
     283              :     }
     284         4915 : }
     285              : 
     286              : 
     287              : /* Unfortunately, class array expressions can appear in various conditions;
     288              :    with and without both _data component and an arrayspec.  This function
     289              :    deals with that variability.  The previous reference to 'ref' is to a
     290              :    class array.  */
     291              : 
     292              : static bool
     293         7145 : class_array_ref_detected (gfc_ref *ref, bool *full_array)
     294              : {
     295         7145 :   bool no_data = false;
     296         7145 :   bool with_data = false;
     297              : 
     298              :   /* An array reference with no _data component.  */
     299         7145 :   if (ref && ref->type == REF_ARRAY
     300          445 :         && !ref->next
     301          445 :         && ref->u.ar.type != AR_ELEMENT)
     302              :     {
     303          445 :       if (full_array)
     304          445 :         *full_array = ref->u.ar.type == AR_FULL;
     305          445 :       no_data = true;
     306              :     }
     307              : 
     308              :   /* Cover cases where _data appears, with or without an array ref.  */
     309         7559 :   if (ref && ref->type == REF_COMPONENT
     310         6669 :         && strcmp (ref->u.c.component->name, "_data") == 0)
     311              :     {
     312         6663 :       if (!ref->next)
     313              :         {
     314            0 :           with_data = true;
     315            0 :           if (full_array)
     316            0 :             *full_array = true;
     317              :         }
     318         6663 :       else if (ref->next && ref->next->type == REF_ARRAY
     319              :             && ref->type == REF_COMPONENT
     320         6663 :             && ref->next->u.ar.type != AR_ELEMENT)
     321              :         {
     322         6273 :           with_data = true;
     323         6273 :           if (full_array)
     324         2814 :             *full_array = ref->next->u.ar.type == AR_FULL;
     325              :         }
     326              :     }
     327              : 
     328         7145 :   return no_data || with_data;
     329              : }
     330              : 
     331              : 
     332              : /* Returns true if the expression contains a reference to a class
     333              :    array.  Notice that class array elements return false.  */
     334              : 
     335              : bool
     336       270597 : gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
     337              : {
     338       270597 :   gfc_ref *ref;
     339              : 
     340       270597 :   if (!e->rank)
     341              :     return false;
     342              : 
     343       234037 :   if (full_array)
     344         3289 :     *full_array= false;
     345              : 
     346              :   /* Is this a class array object? ie. Is the symbol of type class?  */
     347       234037 :   if (e->symtree
     348       191400 :         && e->symtree->n.sym->ts.type == BT_CLASS
     349         6869 :         && CLASS_DATA (e->symtree->n.sym)
     350         6869 :         && CLASS_DATA (e->symtree->n.sym)->attr.dimension
     351       240003 :         && class_array_ref_detected (e->ref, full_array))
     352              :     return true;
     353              : 
     354              :   /* Or is this a class array component reference?  */
     355       423055 :   for (ref = e->ref; ref; ref = ref->next)
     356              :     {
     357       195736 :       if (ref->type == REF_COMPONENT
     358        19427 :             && ref->u.c.component->ts.type == BT_CLASS
     359         1325 :             && CLASS_DATA (ref->u.c.component)->attr.dimension
     360       196915 :             && class_array_ref_detected (ref->next, full_array))
     361              :         return true;
     362              :     }
     363              : 
     364              :   return false;
     365              : }
     366              : 
     367              : 
     368              : /* Returns true if the expression is a reference to a class
     369              :    scalar.  This function is necessary because such expressions
     370              :    can be dressed with a reference to the _data component and so
     371              :    have a type other than BT_CLASS.  */
     372              : 
     373              : bool
     374        46930 : gfc_is_class_scalar_expr (gfc_expr *e)
     375              : {
     376        46930 :   gfc_ref *ref;
     377              : 
     378        46930 :   if (e->rank)
     379              :     return false;
     380              : 
     381              :   /* Is this a class object?  */
     382        41668 :   if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS
     383         2038 :       && CLASS_DATA (e->symtree->n.sym)
     384         2038 :       && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
     385         1756 :       && (e->ref == NULL
     386         1337 :           || (e->ref->type == REF_COMPONENT
     387         1335 :               && strcmp (e->ref->u.c.component->name, "_data") == 0
     388         1030 :               && (e->ref->next == NULL
     389           37 :                   || (e->ref->next->type == REF_ARRAY
     390           37 :                       && e->ref->next->u.ar.codimen > 0
     391           37 :                       && e->ref->next->u.ar.dimen == 0
     392           37 :                       && e->ref->next->next == NULL)))))
     393              :     return true;
     394              : 
     395              :   /* Or is the final reference BT_CLASS or _data?  */
     396        43720 :   for (ref = e->ref; ref; ref = ref->next)
     397              :     {
     398         3956 :       if (ref->type == REF_COMPONENT && ref->u.c.component->ts.type == BT_CLASS
     399          571 :           && CLASS_DATA (ref->u.c.component)
     400          571 :           && !CLASS_DATA (ref->u.c.component)->attr.dimension
     401          505 :           && (ref->next == NULL
     402          367 :               || (ref->next->type == REF_COMPONENT
     403          365 :                   && strcmp (ref->next->u.c.component->name, "_data") == 0
     404          365 :                   && (ref->next->next == NULL
     405           42 :                       || (ref->next->next->type == REF_ARRAY
     406            6 :                           && ref->next->next->u.ar.codimen > 0
     407            6 :                           && ref->next->next->u.ar.dimen == 0
     408            6 :                           && ref->next->next->next == NULL)))))
     409              :         return true;
     410              :     }
     411              : 
     412              :   return false;
     413              : }
     414              : 
     415              : 
     416              : /* Tells whether the expression E is a reference to a (scalar) class container.
     417              :    Scalar because array class containers usually have an array reference after
     418              :    them, and gfc_fix_class_refs will add the missing "_data" component reference
     419              :    in that case.  */
     420              : 
     421              : bool
     422         1376 : gfc_is_class_container_ref (gfc_expr *e)
     423              : {
     424         1376 :   gfc_ref *ref;
     425         1376 :   bool result;
     426              : 
     427         1376 :   if (e->expr_type != EXPR_VARIABLE)
     428          242 :     return e->ts.type == BT_CLASS;
     429              : 
     430         1134 :   if (e->symtree->n.sym->ts.type == BT_CLASS)
     431              :     result = true;
     432              :   else
     433          912 :     result = false;
     434              : 
     435         2457 :   for (ref = e->ref; ref; ref = ref->next)
     436              :     {
     437         1323 :       if (ref->type != REF_COMPONENT)
     438              :         result = false;
     439          289 :       else if (ref->u.c.component->ts.type == BT_CLASS)
     440              :         result = true;
     441              :       else
     442         1323 :         result = false;
     443              :     }
     444              : 
     445              :   return result;
     446              : }
     447              : 
     448              : 
     449              : /* Build an initializer for CLASS pointers,
     450              :    initializing the _data component to the init_expr (or NULL) and the _vptr
     451              :    component to the corresponding type (or the declared type, given by ts).  */
     452              : 
     453              : gfc_expr *
     454         3396 : gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
     455              : {
     456         3396 :   gfc_expr *init;
     457         3396 :   gfc_component *comp;
     458         3396 :   gfc_symbol *vtab = NULL;
     459              : 
     460         3396 :   if (init_expr && init_expr->expr_type != EXPR_NULL)
     461         1653 :     vtab = gfc_find_vtab (&init_expr->ts);
     462              :   else
     463         1743 :     vtab = gfc_find_vtab (ts);
     464              : 
     465         6792 :   init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
     466         3396 :                                              &ts->u.derived->declared_at);
     467         3396 :   init->ts = *ts;
     468              : 
     469        10705 :   for (comp = ts->u.derived->components; comp; comp = comp->next)
     470              :     {
     471         7309 :       gfc_constructor *ctor = gfc_constructor_get();
     472         7309 :       if (strcmp (comp->name, "_vptr") == 0 && vtab)
     473         3396 :         ctor->expr = gfc_lval_expr_from_sym (vtab);
     474         3913 :       else if (init_expr && init_expr->expr_type != EXPR_NULL)
     475         1891 :           ctor->expr = gfc_copy_expr (init_expr);
     476              :       else
     477         2022 :         ctor->expr = gfc_get_null_expr (NULL);
     478         7309 :       gfc_constructor_append (&init->value.constructor, ctor);
     479              :     }
     480              : 
     481         3396 :   return init;
     482              : }
     483              : 
     484              : 
     485              : /* Create a unique string identifier for a derived type, composed of its name
     486              :    and module name. This is used to construct unique names for the class
     487              :    containers and vtab symbols.  */
     488              : 
     489              : static char *
     490       106373 : get_unique_type_string (gfc_symbol *derived)
     491              : {
     492       106373 :   const char *dt_name;
     493       106373 :   char *string;
     494       106373 :   size_t len;
     495       106373 :   if (derived->attr.unlimited_polymorphic)
     496              :     dt_name = "STAR";
     497              :   else
     498        99364 :     dt_name = gfc_dt_upper_string (derived->name);
     499       106373 :   len = strlen (dt_name) + 2;
     500       106373 :   if (derived->attr.unlimited_polymorphic)
     501              :     {
     502         7009 :       string = XNEWVEC (char, len);
     503         7009 :       sprintf (string, "_%s", dt_name);
     504              :     }
     505        99364 :   else if (derived->module)
     506              :     {
     507        39998 :       string = XNEWVEC (char, strlen (derived->module) + len);
     508        39998 :       sprintf (string, "%s_%s", derived->module, dt_name);
     509              :     }
     510        59366 :   else if (derived->ns->proc_name)
     511              :     {
     512        58572 :       string = XNEWVEC (char, strlen (derived->ns->proc_name->name) + len);
     513        58572 :       sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
     514              :     }
     515              :   else
     516              :     {
     517          794 :       string = XNEWVEC (char, len);
     518          794 :       sprintf (string, "_%s", dt_name);
     519              :     }
     520       106373 :   return string;
     521              : }
     522              : 
     523              : 
     524              : /* A relative of 'get_unique_type_string' which makes sure the generated
     525              :    string will not be too long (replacing it by a hash string if needed).  */
     526              : 
     527              : static void
     528        91438 : get_unique_hashed_string (char *string, gfc_symbol *derived)
     529              : {
     530              :   /* Provide sufficient space to hold "symbol.symbol_symbol".  */
     531        91438 :   char *tmp;
     532        91438 :   tmp = get_unique_type_string (derived);
     533              :   /* If string is too long, use hash value in hex representation (allow for
     534              :      extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
     535              :      We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
     536              :      where %d is the (co)rank which can be up to n = 15.  */
     537        91438 :   if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
     538              :     {
     539          141 :       int h = gfc_hash_value (derived);
     540          141 :       sprintf (string, "%X", h);
     541              :     }
     542              :   else
     543        91297 :     strcpy (string, tmp);
     544        91438 :   free (tmp);
     545        91438 : }
     546              : 
     547              : 
     548              : /* Assign a hash value for a derived type. The algorithm is that of SDBM.  */
     549              : 
     550              : unsigned int
     551        14935 : gfc_hash_value (gfc_symbol *sym)
     552              : {
     553        14935 :   unsigned int hash = 0;
     554              :   /* Provide sufficient space to hold "symbol.symbol_symbol".  */
     555        14935 :   char *c;
     556        14935 :   int i, len;
     557              : 
     558        14935 :   c = get_unique_type_string (sym);
     559        14935 :   len = strlen (c);
     560              : 
     561       239236 :   for (i = 0; i < len; i++)
     562       224301 :     hash = (hash << 6) + (hash << 16) - hash + c[i];
     563              : 
     564        14935 :   free (c);
     565              :   /* Return the hash but take the modulus for the sake of module read,
     566              :      even though this slightly increases the chance of collision.  */
     567        14935 :   return (hash % 100000000);
     568              : }
     569              : 
     570              : 
     571              : /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM.  */
     572              : 
     573              : unsigned int
     574          930 : gfc_intrinsic_hash_value (gfc_typespec *ts)
     575              : {
     576          930 :   unsigned int hash = 0;
     577          930 :   const char *c = gfc_typename (ts, true);
     578          930 :   int i, len;
     579              : 
     580          930 :   len = strlen (c);
     581              : 
     582        10118 :   for (i = 0; i < len; i++)
     583         9188 :     hash = (hash << 6) + (hash << 16) - hash + c[i];
     584              : 
     585              :   /* Return the hash but take the modulus for the sake of module read,
     586              :      even though this slightly increases the chance of collision.  */
     587          930 :   return (hash % 100000000);
     588              : }
     589              : 
     590              : 
     591              : /* Get the _len component from a class/derived object storing a string.
     592              :    For unlimited polymorphic entities a ref to the _data component is available
     593              :    while a ref to the _len component is needed.  This routine traverese the
     594              :    ref-chain and strips the last ref to a _data from it replacing it with a
     595              :    ref to the _len component.  */
     596              : 
     597              : gfc_expr *
     598          367 : gfc_get_len_component (gfc_expr *e, int k)
     599              : {
     600          367 :   gfc_expr *ptr;
     601          367 :   gfc_ref *ref, **last;
     602              : 
     603          367 :   ptr = gfc_copy_expr (e);
     604              : 
     605              :   /* We need to remove the last _data component ref from ptr.  */
     606          367 :   last = &(ptr->ref);
     607          367 :   ref = ptr->ref;
     608          367 :   while (ref)
     609              :     {
     610          367 :       if (!ref->next
     611          367 :           && ref->type == REF_COMPONENT
     612          367 :           && strcmp ("_data", ref->u.c.component->name)== 0)
     613              :         {
     614          367 :           gfc_free_ref_list (ref);
     615          367 :           *last = NULL;
     616          367 :           break;
     617              :         }
     618            0 :       last = &(ref->next);
     619            0 :       ref = ref->next;
     620              :     }
     621              :   /* And replace if with a ref to the _len component.  */
     622          367 :   gfc_add_len_component (ptr);
     623          367 :   if (k != ptr->ts.kind)
     624              :     {
     625          367 :       gfc_typespec ts;
     626          367 :       gfc_clear_ts (&ts);
     627          367 :       ts.type = BT_INTEGER;
     628          367 :       ts.kind = k;
     629          367 :       gfc_convert_type_warn (ptr, &ts, 2, 0);
     630              :     }
     631          367 :   return ptr;
     632              : }
     633              : 
     634              : 
     635              : /* Build a polymorphic CLASS entity, using the symbol that comes from
     636              :    build_sym. A CLASS entity is represented by an encapsulating type,
     637              :    which contains the declared type as '_data' component, plus a pointer
     638              :    component '_vptr' which determines the dynamic type.  When this CLASS
     639              :    entity is unlimited polymorphic, then also add a component '_len' to
     640              :    store the length of string when that is stored in it.  */
     641              : static int ctr = 0;
     642              : 
     643              : bool
     644        12925 : gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
     645              :                         gfc_array_spec **as)
     646              : {
     647        12925 :   char tname[GFC_MAX_SYMBOL_LEN+1];
     648        12925 :   char *name;
     649        12925 :   gfc_typespec *orig_ts = ts;
     650        12925 :   gfc_symbol *fclass;
     651        12925 :   gfc_symbol *vtab;
     652        12925 :   gfc_component *c;
     653        12925 :   gfc_namespace *ns;
     654        12925 :   int rank;
     655              : 
     656        12925 :   gcc_assert (as);
     657              : 
     658              :   /* We cannot build the class container now.  */
     659        12925 :   if (attr->class_ok && (!ts->u.derived || !ts->u.derived->components))
     660              :     return false;
     661              : 
     662              :   /* Class container has already been built with same name.  */
     663        12924 :   if (attr->class_ok
     664           34 :       && ts->u.derived->components->attr.dimension >= attr->dimension
     665           21 :       && ts->u.derived->components->attr.codimension >= attr->codimension
     666           16 :       && ts->u.derived->components->attr.class_pointer >= attr->pointer
     667           10 :       && ts->u.derived->components->attr.allocatable >= attr->allocatable)
     668              :     return true;
     669        12923 :   if (attr->class_ok)
     670              :     {
     671           33 :       attr->dimension |= ts->u.derived->components->attr.dimension;
     672           33 :       attr->codimension |= ts->u.derived->components->attr.codimension;
     673           33 :       attr->pointer |= ts->u.derived->components->attr.class_pointer;
     674           33 :       attr->allocatable |= ts->u.derived->components->attr.allocatable;
     675           33 :       ts = &ts->u.derived->components->ts;
     676              :     }
     677              : 
     678         6172 :   attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
     679        13169 :                    || attr->select_type_temporary || attr->associate_var;
     680              : 
     681        12923 :   if (!attr->class_ok)
     682              :     /* We cannot build the class container yet.  */
     683              :     return true;
     684              : 
     685              :   /* Determine the name of the encapsulating type.  */
     686        12848 :   rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
     687              : 
     688        12848 :   if (!ts->u.derived)
     689              :     return false;
     690              : 
     691        12843 :   get_unique_hashed_string (tname, ts->u.derived);
     692        12843 :   if ((*as) && attr->allocatable)
     693         1996 :     name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
     694        10847 :   else if ((*as) && attr->pointer)
     695         1185 :     name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
     696         9662 :   else if ((*as))
     697         1181 :     name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
     698         8481 :   else if (attr->pointer)
     699         1777 :     name = xasprintf ("__class_%s_p", tname);
     700         6704 :   else if (attr->allocatable)
     701         2142 :     name = xasprintf ("__class_%s_a", tname);
     702              :   else
     703         4562 :     name = xasprintf ("__class_%s_t", tname);
     704              : 
     705        12843 :   if (ts->u.derived->attr.unlimited_polymorphic)
     706              :     {
     707              :       /* Find the top-level namespace.  */
     708         4696 :       for (ns = gfc_current_ns; ns; ns = ns->parent)
     709         4696 :         if (!ns->parent)
     710              :           break;
     711              :     }
     712              :   else
     713        10303 :     ns = ts->u.derived->ns;
     714              : 
     715              :   /* Although this might seem to be counterintuitive, we can build separate
     716              :      class types with different array specs because the TKR interface checks
     717              :      work on the declared type. All array type other than deferred shape or
     718              :      assumed rank are added to the function namespace to ensure that they
     719              :      are properly distinguished.  */
     720        12843 :   if (attr->dummy && (*as)
     721         1864 :       && ((!attr->codimension
     722         1694 :            && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK))
     723         1629 :           || (attr->codimension
     724          170 :               && !((*as)->cotype == AS_DEFERRED
     725              :                    || (*as)->cotype == AS_ASSUMED_RANK))))
     726              :     {
     727          336 :       char *sname;
     728          336 :       ns = gfc_current_ns;
     729          336 :       gfc_find_symbol (name, ns, 0, &fclass);
     730              :       /* If a local class type with this name already exists, update the
     731              :          name with an index.  */
     732          336 :       if (fclass)
     733              :         {
     734           16 :           fclass = NULL;
     735           16 :           sname = xasprintf ("%s_%d", name, ++ctr);
     736           16 :           free (name);
     737           16 :           name = sname;
     738              :         }
     739              :     }
     740              :   else
     741        12507 :     gfc_find_symbol (name, ns, 0, &fclass);
     742              : 
     743        12843 :   if (fclass == NULL)
     744              :     {
     745         7786 :       gfc_symtree *st;
     746              :       /* If not there, create a new symbol.  */
     747         7786 :       fclass = gfc_new_symbol (name, ns);
     748         7786 :       st = gfc_new_symtree (&ns->sym_root, name);
     749         7786 :       st->n.sym = fclass;
     750         7786 :       gfc_set_sym_referenced (fclass);
     751         7786 :       fclass->refs++;
     752         7786 :       fclass->ts.type = BT_UNKNOWN;
     753         7786 :       if (!ts->u.derived->attr.unlimited_polymorphic)
     754         6224 :         fclass->attr.abstract = ts->u.derived->attr.abstract;
     755         7786 :       fclass->f2k_derived = gfc_get_namespace (NULL, 0);
     756         7786 :       if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
     757              :                            &gfc_current_locus))
     758              :         return false;
     759              : 
     760              :       /* Add component '_data'.  */
     761         7786 :       if (!gfc_add_component (fclass, "_data", &c))
     762              :         return false;
     763         7786 :       c->ts = *ts;
     764         7786 :       c->ts.type = BT_DERIVED;
     765         7786 :       c->attr.access = ACCESS_PRIVATE;
     766         7786 :       c->ts.u.derived = ts->u.derived;
     767         7786 :       c->attr.class_pointer = attr->pointer;
     768         6106 :       c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
     769        10508 :                         || attr->select_type_temporary;
     770         7786 :       c->attr.allocatable = attr->allocatable;
     771         7786 :       c->attr.dimension = attr->dimension;
     772         7786 :       c->attr.codimension = attr->codimension;
     773         7786 :       c->attr.abstract = fclass->attr.abstract;
     774         7786 :       c->as = (*as);
     775         7786 :       c->initializer = NULL;
     776              : 
     777              :       /* Add component '_vptr'.  */
     778         7786 :       if (!gfc_add_component (fclass, "_vptr", &c))
     779              :         return false;
     780         7786 :       c->ts.type = BT_DERIVED;
     781         7786 :       c->attr.access = ACCESS_PRIVATE;
     782         7786 :       c->attr.pointer = 1;
     783              : 
     784         7786 :       if (ts->u.derived->attr.unlimited_polymorphic)
     785              :         {
     786         1562 :           vtab = gfc_find_derived_vtab (ts->u.derived);
     787         1562 :           gcc_assert (vtab);
     788         1562 :           c->ts.u.derived = vtab->ts.u.derived;
     789              : 
     790              :           /* Add component '_len'.  Only unlimited polymorphic pointers may
     791              :              have a string assigned to them, i.e., only those need the _len
     792              :              component.  */
     793         1562 :           if (!gfc_add_component (fclass, "_len", &c))
     794              :             return false;
     795         1562 :           c->ts.type = BT_INTEGER;
     796         1562 :           c->ts.kind = gfc_charlen_int_kind;
     797         1562 :           c->attr.access = ACCESS_PRIVATE;
     798         1562 :           c->attr.artificial = 1;
     799              :         }
     800              :       else
     801              :         /* Build vtab later.  */
     802         6224 :         c->ts.u.derived = NULL;
     803              :     }
     804              : 
     805        12843 :   if (!ts->u.derived->attr.unlimited_polymorphic)
     806              :     {
     807              :       /* Since the extension field is 8 bit wide, we can only have
     808              :          up to 255 extension levels.  */
     809        10303 :       if (ts->u.derived->attr.extension == 255)
     810              :         {
     811            0 :           gfc_error ("Maximum extension level reached with type %qs at %L",
     812              :                      ts->u.derived->name, &ts->u.derived->declared_at);
     813            0 :         return false;
     814              :         }
     815              : 
     816        10303 :       fclass->attr.extension = ts->u.derived->attr.extension + 1;
     817        10303 :       fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
     818        10303 :       fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
     819              :     }
     820              : 
     821        12843 :   fclass->attr.is_class = 1;
     822        12843 :   orig_ts->u.derived = fclass;
     823        12843 :   attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
     824        12843 :   (*as) = NULL;
     825        12843 :   free (name);
     826        12843 :   return true;
     827              : }
     828              : 
     829              : 
     830              : /* Change class, using gfc_build_class_symbol. This is needed for associate
     831              :    names, when rank changes or a derived type is produced by resolution.  */
     832              : 
     833              : void
     834          109 : gfc_change_class (gfc_typespec *ts, symbol_attribute *sym_attr,
     835              :                   gfc_array_spec *sym_as, int rank, int corank)
     836              : {
     837          109 :   symbol_attribute attr;
     838          109 :   gfc_component *c;
     839          109 :   gfc_array_spec *as = NULL;
     840          109 :   gfc_symbol *der = ts->u.derived;
     841              : 
     842          109 :   ts->type = BT_CLASS;
     843          109 :   attr = *sym_attr;
     844          109 :   attr.class_ok = 0;
     845          109 :   attr.associate_var = 1;
     846          109 :   attr.class_pointer = 1;
     847          109 :   attr.allocatable = 0;
     848          109 :   attr.pointer = 1;
     849          109 :   attr.dimension = rank ? 1 : 0;
     850           13 :   if (rank)
     851              :     {
     852           96 :       if (sym_as)
     853           18 :         as = gfc_copy_array_spec (sym_as);
     854              :       else
     855              :         {
     856           78 :           as = gfc_get_array_spec ();
     857           78 :           as->rank = rank;
     858           78 :           as->type = AS_DEFERRED;
     859           78 :           as->corank = corank;
     860              :         }
     861              :     }
     862          109 :   if (as && as->corank != 0)
     863            0 :     attr.codimension = 1;
     864              : 
     865          109 :   if (!gfc_build_class_symbol (ts, &attr, &as))
     866            0 :     gcc_unreachable ();
     867              : 
     868          109 :   gfc_set_sym_referenced (ts->u.derived);
     869              : 
     870              :   /* Make sure the _vptr is set.  */
     871          109 :   c = gfc_find_component (ts->u.derived, "_vptr", true, true, NULL);
     872          109 :   if (c->ts.u.derived == NULL)
     873           48 :     c->ts.u.derived = gfc_find_derived_vtab (der);
     874              :   /* _vptr now has the _vtab in it, change it to the _vtype.  */
     875          109 :   if (c->ts.u.derived->attr.vtab)
     876           48 :     c->ts.u.derived = c->ts.u.derived->ts.u.derived;
     877          109 : }
     878              : 
     879              : 
     880              : /* Add a procedure pointer component to the vtype
     881              :    to represent a specific type-bound procedure.  */
     882              : 
     883              : static void
     884         4722 : add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
     885              : {
     886         4722 :   gfc_component *c;
     887         4722 :   bool is_abstract = false;
     888              : 
     889         4722 :   c = gfc_find_component (vtype, name, true, true, NULL);
     890              : 
     891              :   /* If the present component typebound proc is abstract, the new version
     892              :      should unconditionally be tested if it is a suitable replacement.  */
     893         4722 :   if (c && c->tb && c->tb->u.specific
     894         1313 :       && c->tb->u.specific->n.sym->attr.abstract)
     895         4722 :     is_abstract = true;
     896              : 
     897              :   /* Pass on the new tb being not overridable if a component is found and
     898              :      either there is not an overridden specific or the present component
     899              :      tb is abstract. This ensures that possible, viable replacements are
     900              :      loaded.  */
     901         4722 :   if (tb->non_overridable && !tb->overridden && !is_abstract && c)
     902            7 :     return;
     903              : 
     904         4715 :   if (c == NULL)
     905              :     {
     906              :       /* Add procedure component.  */
     907         3391 :       if (!gfc_add_component (vtype, name, &c))
     908              :         return;
     909              : 
     910         3391 :       if (!c->tb)
     911         3391 :         c->tb = XCNEW (gfc_typebound_proc);
     912         3391 :       *c->tb = *tb;
     913         3391 :       c->tb->ppc = 1;
     914         3391 :       c->attr.procedure = 1;
     915         3391 :       c->attr.proc_pointer = 1;
     916         3391 :       c->attr.flavor = FL_PROCEDURE;
     917         3391 :       c->attr.access = ACCESS_PRIVATE;
     918         3391 :       c->attr.external = 1;
     919         3391 :       c->attr.untyped = 1;
     920         3391 :       c->attr.if_source = IFSRC_IFBODY;
     921              :     }
     922         1324 :   else if (c->attr.proc_pointer && c->tb)
     923              :     {
     924         1324 :       *c->tb = *tb;
     925         1324 :       c->tb->ppc = 1;
     926              :     }
     927              : 
     928         4715 :   if (tb->u.specific)
     929              :     {
     930         4697 :       gfc_symbol *ifc = tb->u.specific->n.sym;
     931         4697 :       c->ts.interface = ifc;
     932         4697 :       if (!tb->deferred)
     933         3969 :         c->initializer = gfc_get_variable_expr (tb->u.specific);
     934         4697 :       c->attr.pure = ifc->attr.pure;
     935              :     }
     936              : }
     937              : 
     938              : 
     939              : /* Add all specific type-bound procedures in the symtree 'st' to a vtype.  */
     940              : 
     941              : static void
     942         4605 : add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
     943              : {
     944         4605 :   if (!st)
     945              :     return;
     946              : 
     947         4605 :   if (st->left)
     948         1185 :     add_procs_to_declared_vtab1 (st->left, vtype);
     949              : 
     950         4605 :   if (st->right)
     951         1120 :     add_procs_to_declared_vtab1 (st->right, vtype);
     952              : 
     953         4605 :   if (st->n.tb && !st->n.tb->error
     954         4543 :       && !st->n.tb->is_generic && st->n.tb->u.specific)
     955         3922 :     add_proc_comp (vtype, st->name, st->n.tb);
     956              : }
     957              : 
     958              : 
     959              : /* Copy procedure pointers components from the parent type.  */
     960              : 
     961              : static void
     962         1454 : copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
     963              : {
     964         1454 :   gfc_component *cmp;
     965         1454 :   gfc_symbol *vtab;
     966              : 
     967         1454 :   vtab = gfc_find_derived_vtab (declared);
     968              : 
     969        12468 :   for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
     970              :     {
     971        11014 :       if (gfc_find_component (vtype, cmp->name, true, true, NULL))
     972        10214 :         continue;
     973              : 
     974          800 :       add_proc_comp (vtype, cmp->name, cmp->tb);
     975              :     }
     976         1454 : }
     977              : 
     978              : 
     979              : /* Returns true if any of its nonpointer nonallocatable components or
     980              :    their nonpointer nonallocatable subcomponents has a finalization
     981              :    subroutine.  */
     982              : 
     983              : static bool
     984         9949 : has_finalizer_component (gfc_symbol *derived)
     985              : {
     986         9949 :    gfc_component *c;
     987              : 
     988        21416 :   for (c = derived->components; c; c = c->next)
     989        11497 :     if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable
     990         1908 :         && c->attr.flavor != FL_PROCEDURE)
     991              :       {
     992         1902 :         if (c->ts.u.derived->f2k_derived
     993         1805 :             && c->ts.u.derived->f2k_derived->finalizers)
     994              :           return true;
     995              : 
     996              :         /* Stop infinite recursion through this function by inhibiting
     997              :           calls when the derived type and that of the component are
     998              :           the same.  */
     999         1872 :         if (!gfc_compare_derived_types (derived, c->ts.u.derived)
    1000         1872 :             && has_finalizer_component (c->ts.u.derived))
    1001              :           return true;
    1002              :       }
    1003              :   return false;
    1004              : }
    1005              : 
    1006              : 
    1007              : static bool
    1008         7420 : comp_is_finalizable (gfc_component *comp)
    1009              : {
    1010         7420 :   if (comp->attr.proc_pointer)
    1011              :     return false;
    1012         7342 :   else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
    1013              :     return true;
    1014         1118 :   else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
    1015         4662 :            && (comp->ts.u.derived->attr.alloc_comp
    1016          468 :                || has_finalizer_component (comp->ts.u.derived)
    1017          468 :                || (comp->ts.u.derived->f2k_derived
    1018          444 :                    && comp->ts.u.derived->f2k_derived->finalizers)))
    1019          715 :     return true;
    1020         2879 :   else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1021          638 :             && CLASS_DATA (comp)->attr.allocatable)
    1022              :     return true;
    1023              :   else
    1024              :     return false;
    1025              : }
    1026              : 
    1027              : 
    1028              : /* Call DEALLOCATE for the passed component if it is allocatable, if it is
    1029              :    neither allocatable nor a pointer but has a finalizer, call it. If it
    1030              :    is a nonpointer component with allocatable components or has finalizers, walk
    1031              :    them. Either of them is required; other nonallocatables and pointers aren't
    1032              :    handled gracefully.
    1033              :    Note: If the component is allocatable, the DEALLOCATE handling takes care
    1034              :    of calling the appropriate finalizers, coarray deregistering, and
    1035              :    deallocation of allocatable subcomponents.  */
    1036              : 
    1037              : static bool
    1038         3778 : finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
    1039              :                     gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
    1040              :                     gfc_namespace *sub_ns)
    1041              : {
    1042         3778 :   gfc_expr *e;
    1043         3778 :   gfc_ref *ref;
    1044         3778 :   gfc_was_finalized *f;
    1045              : 
    1046         3778 :   if (!comp_is_finalizable (comp))
    1047              :     return false;
    1048              : 
    1049              :   /* If this expression with this component has been finalized
    1050              :      already in this namespace, there is nothing to do.  */
    1051         3805 :   for (f = sub_ns->was_finalized; f; f = f->next)
    1052              :     {
    1053         1069 :       if (f->e == expr && f->c == comp)
    1054              :         return false;
    1055              :     }
    1056              : 
    1057         2736 :   e = gfc_copy_expr (expr);
    1058         2736 :   if (!e->ref)
    1059         2337 :     e->ref = ref = gfc_get_ref ();
    1060              :   else
    1061              :     {
    1062          538 :       for (ref = e->ref; ref->next; ref = ref->next)
    1063              :         ;
    1064          399 :       ref->next = gfc_get_ref ();
    1065          399 :       ref = ref->next;
    1066              :     }
    1067         2736 :   ref->type = REF_COMPONENT;
    1068         2736 :   ref->u.c.sym = derived;
    1069         2736 :   ref->u.c.component = comp;
    1070         2736 :   e->ts = comp->ts;
    1071              : 
    1072         2736 :   if (comp->attr.dimension || comp->attr.codimension
    1073         1192 :       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1074          332 :           && (CLASS_DATA (comp)->attr.dimension
    1075          221 :               || CLASS_DATA (comp)->attr.codimension)))
    1076              :     {
    1077         1663 :       ref->next = gfc_get_ref ();
    1078         1663 :       ref->next->type = REF_ARRAY;
    1079         1663 :       ref->next->u.ar.dimen = 0;
    1080         1663 :       ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
    1081              :                                                         : comp->as;
    1082         1663 :       e->rank = ref->next->u.ar.as->rank;
    1083         1663 :       e->corank = ref->next->u.ar.as->corank;
    1084         1682 :       ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
    1085              :     }
    1086              : 
    1087              :   /* Call DEALLOCATE (comp, stat=ignore).  */
    1088         2736 :   if (comp->attr.allocatable
    1089          716 :       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1090          332 :           && CLASS_DATA (comp)->attr.allocatable))
    1091              :     {
    1092         2352 :       gfc_code *dealloc, *block = NULL;
    1093              : 
    1094              :       /* Add IF (fini_coarray).  */
    1095         2352 :       if (comp->attr.codimension
    1096         2335 :           || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1097          332 :               && CLASS_DATA (comp)->attr.codimension))
    1098              :         {
    1099           31 :           block = gfc_get_code (EXEC_IF);
    1100           31 :           if (*code)
    1101              :             {
    1102           31 :               (*code)->next = block;
    1103           31 :               (*code) = (*code)->next;
    1104              :             }
    1105              :           else
    1106            0 :               (*code) = block;
    1107              : 
    1108           31 :           block->block = gfc_get_code (EXEC_IF);
    1109           31 :           block = block->block;
    1110           31 :           block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
    1111              :         }
    1112              : 
    1113         2352 :       dealloc = gfc_get_code (EXEC_DEALLOCATE);
    1114              : 
    1115         2352 :       dealloc->ext.alloc.list = gfc_get_alloc ();
    1116         2352 :       dealloc->ext.alloc.list->expr = e;
    1117         2352 :       dealloc->expr1 = gfc_lval_expr_from_sym (stat);
    1118              : 
    1119         2352 :       gfc_code *cond = gfc_get_code (EXEC_IF);
    1120         2352 :       cond->block = gfc_get_code (EXEC_IF);
    1121         2352 :       cond->block->expr1 = gfc_get_expr ();
    1122         2352 :       cond->block->expr1->expr_type = EXPR_FUNCTION;
    1123         2352 :       cond->block->expr1->where = gfc_current_locus;
    1124         2352 :       gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
    1125         2352 :       cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
    1126         2352 :       cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
    1127         2352 :       cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
    1128         2352 :       gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
    1129         2352 :       cond->block->expr1->ts.type = BT_LOGICAL;
    1130         2352 :       cond->block->expr1->ts.kind = gfc_default_logical_kind;
    1131         2352 :       cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
    1132         2352 :       cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
    1133         2352 :       cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
    1134         2352 :       cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
    1135         2352 :       cond->block->next = dealloc;
    1136              : 
    1137         2352 :       if (block)
    1138           31 :         block->next = cond;
    1139         2321 :       else if (*code)
    1140              :         {
    1141         2321 :           (*code)->next = cond;
    1142         2321 :           (*code) = (*code)->next;
    1143              :         }
    1144              :       else
    1145            0 :         (*code) = cond;
    1146              : 
    1147              :     }
    1148          384 :   else if (comp->ts.type == BT_DERIVED
    1149          384 :             && comp->ts.u.derived->f2k_derived
    1150          384 :             && comp->ts.u.derived->f2k_derived->finalizers)
    1151              :     {
    1152              :       /* Call FINAL_WRAPPER (comp);  */
    1153           83 :       gfc_code *final_wrap;
    1154           83 :       gfc_symbol *vtab, *byte_stride;
    1155           83 :       gfc_expr *scalar, *size_expr, *fini_coarray_expr;
    1156           83 :       gfc_component *c;
    1157              : 
    1158           83 :       vtab = gfc_find_derived_vtab (comp->ts.u.derived);
    1159          498 :       for (c = vtab->ts.u.derived->components; c; c = c->next)
    1160          498 :         if (strcmp (c->name, "_final") == 0)
    1161              :           break;
    1162              : 
    1163           83 :       gcc_assert (c);
    1164              : 
    1165              :       /* Set scalar argument for storage_size. A leading underscore in
    1166              :          the name prevents an unwanted finalization.  */
    1167           83 :       gfc_get_symbol ("_comp_byte_stride", sub_ns, &byte_stride);
    1168           83 :       byte_stride->ts = e->ts;
    1169           83 :       byte_stride->attr.flavor = FL_VARIABLE;
    1170           83 :       byte_stride->attr.value = 1;
    1171           83 :       byte_stride->attr.artificial = 1;
    1172           83 :       gfc_set_sym_referenced (byte_stride);
    1173           83 :       gfc_commit_symbol (byte_stride);
    1174           83 :       scalar = gfc_lval_expr_from_sym (byte_stride);
    1175              : 
    1176           83 :       final_wrap = gfc_get_code (EXEC_CALL);
    1177           83 :       final_wrap->symtree = c->initializer->symtree;
    1178           83 :       final_wrap->resolved_sym = c->initializer->symtree->n.sym;
    1179           83 :       final_wrap->ext.actual = gfc_get_actual_arglist ();
    1180           83 :       final_wrap->ext.actual->expr = e;
    1181              : 
    1182              :       /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE.  */
    1183           83 :       size_expr = gfc_get_expr ();
    1184           83 :       size_expr->where = gfc_current_locus;
    1185           83 :       size_expr->expr_type = EXPR_OP;
    1186           83 :       size_expr->value.op.op = INTRINSIC_DIVIDE;
    1187              : 
    1188              :       /* STORAGE_SIZE (array,kind=c_intptr_t).  */
    1189           83 :       size_expr->value.op.op1
    1190           83 :         = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
    1191              :                                     "storage_size", gfc_current_locus, 2,
    1192              :                                     scalar,
    1193              :                                     gfc_get_int_expr (gfc_index_integer_kind,
    1194              :                                                       NULL, 0));
    1195              : 
    1196              :       /* NUMERIC_STORAGE_SIZE.  */
    1197           83 :       size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
    1198              :                                                   gfc_character_storage_size);
    1199           83 :       size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
    1200           83 :       size_expr->ts = size_expr->value.op.op1->ts;
    1201              : 
    1202              :       /* Which provides the argument 'byte_stride'.....  */
    1203           83 :       final_wrap->ext.actual->next = gfc_get_actual_arglist ();
    1204           83 :       final_wrap->ext.actual->next->expr = size_expr;
    1205              : 
    1206              :       /* ...and last of all the 'fini_coarray' argument.  */
    1207           83 :       fini_coarray_expr = gfc_lval_expr_from_sym (fini_coarray);
    1208           83 :       final_wrap->ext.actual->next->next = gfc_get_actual_arglist ();
    1209           83 :       final_wrap->ext.actual->next->next->expr = fini_coarray_expr;
    1210              : 
    1211           83 :       if (*code)
    1212              :         {
    1213           83 :           (*code)->next = final_wrap;
    1214           83 :           (*code) = (*code)->next;
    1215              :         }
    1216              :       else
    1217            0 :         (*code) = final_wrap;
    1218           83 :     }
    1219              :   else
    1220              :     {
    1221          301 :       gfc_component *c;
    1222          301 :       bool ret = false;
    1223              : 
    1224          836 :       for (c = comp->ts.u.derived->components; c; c = c->next)
    1225          535 :         ret |= finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray,
    1226              :                                    code, sub_ns);
    1227              :       /* Only free the expression, if it has never been used.  */
    1228          301 :       if (!ret)
    1229            0 :         gfc_free_expr (e);
    1230              :     }
    1231              : 
    1232              :   /* Record that this was finalized already in this namespace.  */
    1233         2736 :   f = sub_ns->was_finalized;
    1234         2736 :   sub_ns->was_finalized = XCNEW (gfc_was_finalized);
    1235         2736 :   sub_ns->was_finalized->e = expr;
    1236         2736 :   sub_ns->was_finalized->c = comp;
    1237         2736 :   sub_ns->was_finalized->next = f;
    1238         2736 :   return true;
    1239              : }
    1240              : 
    1241              : 
    1242              : /* Generate code equivalent to
    1243              :    CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
    1244              :                      + offset, c_ptr), ptr).  */
    1245              : 
    1246              : static gfc_code *
    1247         2451 : finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
    1248              :                          gfc_expr *offset, gfc_namespace *sub_ns)
    1249              : {
    1250         2451 :   gfc_code *block;
    1251         2451 :   gfc_expr *expr, *expr2;
    1252              : 
    1253              :   /* C_F_POINTER().  */
    1254         2451 :   block = gfc_get_code (EXEC_CALL);
    1255         2451 :   gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
    1256         2451 :   block->resolved_sym = block->symtree->n.sym;
    1257         2451 :   block->resolved_sym->attr.flavor = FL_PROCEDURE;
    1258         2451 :   block->resolved_sym->attr.intrinsic = 1;
    1259         2451 :   block->resolved_sym->attr.subroutine = 1;
    1260         2451 :   block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
    1261         2451 :   block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
    1262         2451 :   block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
    1263         2451 :   gfc_commit_symbol (block->resolved_sym);
    1264              : 
    1265              :   /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t).  */
    1266         2451 :   block->ext.actual = gfc_get_actual_arglist ();
    1267         2451 :   block->ext.actual->next = gfc_get_actual_arglist ();
    1268         2451 :   block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
    1269              :                                                     NULL, 0);
    1270         2451 :   block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE.  */
    1271              : 
    1272              :   /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t).  */
    1273              : 
    1274              :   /* TRANSFER's first argument: C_LOC (array).  */
    1275         2451 :   expr = gfc_get_expr ();
    1276         2451 :   expr->expr_type = EXPR_FUNCTION;
    1277         2451 :   gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
    1278         2451 :   expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
    1279         2451 :   expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
    1280         2451 :   expr->symtree->n.sym->attr.intrinsic = 1;
    1281         2451 :   expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
    1282         2451 :   expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
    1283         2451 :   expr->value.function.actual = gfc_get_actual_arglist ();
    1284         2451 :   expr->value.function.actual->expr
    1285         2451 :             = gfc_lval_expr_from_sym (array);
    1286         2451 :   expr->symtree->n.sym->result = expr->symtree->n.sym;
    1287         2451 :   gfc_commit_symbol (expr->symtree->n.sym);
    1288         2451 :   expr->ts.type = BT_INTEGER;
    1289         2451 :   expr->ts.kind = gfc_index_integer_kind;
    1290         2451 :   expr->where = gfc_current_locus;
    1291              : 
    1292              :   /* TRANSFER.  */
    1293         2451 :   expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
    1294              :                                     gfc_current_locus, 3, expr,
    1295              :                                     gfc_get_int_expr (gfc_index_integer_kind,
    1296              :                                                       NULL, 0), NULL);
    1297         2451 :   expr2->ts.type = BT_INTEGER;
    1298         2451 :   expr2->ts.kind = gfc_index_integer_kind;
    1299              : 
    1300              :   /* <array addr> + <offset>.  */
    1301         2451 :   block->ext.actual->expr = gfc_get_expr ();
    1302         2451 :   block->ext.actual->expr->expr_type = EXPR_OP;
    1303         2451 :   block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
    1304         2451 :   block->ext.actual->expr->value.op.op1 = expr2;
    1305         2451 :   block->ext.actual->expr->value.op.op2 = offset;
    1306         2451 :   block->ext.actual->expr->ts = expr->ts;
    1307         2451 :   block->ext.actual->expr->where = gfc_current_locus;
    1308              : 
    1309              :   /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=.  */
    1310         2451 :   block->ext.actual->next = gfc_get_actual_arglist ();
    1311         2451 :   block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
    1312         2451 :   block->ext.actual->next->next = gfc_get_actual_arglist ();
    1313              : 
    1314         2451 :   return block;
    1315              : }
    1316              : 
    1317              : 
    1318              : /* Calculates the offset to the (idx+1)th element of an array, taking the
    1319              :    stride into account. It generates the code:
    1320              :      offset = 0
    1321              :      do idx2 = 1, rank
    1322              :        offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
    1323              :      end do
    1324              :      offset = offset * byte_stride.  */
    1325              : 
    1326              : static gfc_code*
    1327         2229 : finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
    1328              :                          gfc_symbol *strides, gfc_symbol *sizes,
    1329              :                          gfc_symbol *byte_stride, gfc_expr *rank,
    1330              :                          gfc_code *block, gfc_namespace *sub_ns)
    1331              : {
    1332         2229 :   gfc_iterator *iter;
    1333         2229 :   gfc_expr *expr, *expr2;
    1334              : 
    1335              :   /* offset = 0.  */
    1336         2229 :   block->next = gfc_get_code (EXEC_ASSIGN);
    1337         2229 :   block = block->next;
    1338         2229 :   block->expr1 = gfc_lval_expr_from_sym (offset);
    1339         2229 :   block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1340              : 
    1341              :   /* Create loop.  */
    1342         2229 :   iter = gfc_get_iterator ();
    1343         2229 :   iter->var = gfc_lval_expr_from_sym (idx2);
    1344         2229 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1345         2229 :   iter->end = gfc_copy_expr (rank);
    1346         2229 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1347         2229 :   block->next = gfc_get_code (EXEC_DO);
    1348         2229 :   block = block->next;
    1349         2229 :   block->ext.iterator = iter;
    1350         2229 :   block->block = gfc_get_code (EXEC_DO);
    1351              : 
    1352              :   /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
    1353              :                                   * strides(idx2).  */
    1354              : 
    1355              :   /* mod (idx, sizes(idx2)).  */
    1356         2229 :   expr = gfc_lval_expr_from_sym (sizes);
    1357         2229 :   expr->ref = gfc_get_ref ();
    1358         2229 :   expr->ref->type = REF_ARRAY;
    1359         2229 :   expr->ref->u.ar.as = sizes->as;
    1360         2229 :   expr->ref->u.ar.type = AR_ELEMENT;
    1361         2229 :   expr->ref->u.ar.dimen = 1;
    1362         2229 :   expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1363         2229 :   expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
    1364         2229 :   expr->where = sizes->declared_at;
    1365              : 
    1366         2229 :   expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
    1367              :                                    gfc_current_locus, 2,
    1368              :                                    gfc_lval_expr_from_sym (idx), expr);
    1369         2229 :   expr->ts = idx->ts;
    1370              : 
    1371              :   /* (...) / sizes(idx2-1).  */
    1372         2229 :   expr2 = gfc_get_expr ();
    1373         2229 :   expr2->expr_type = EXPR_OP;
    1374         2229 :   expr2->value.op.op = INTRINSIC_DIVIDE;
    1375         2229 :   expr2->value.op.op1 = expr;
    1376         2229 :   expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
    1377         2229 :   expr2->value.op.op2->ref = gfc_get_ref ();
    1378         2229 :   expr2->value.op.op2->ref->type = REF_ARRAY;
    1379         2229 :   expr2->value.op.op2->ref->u.ar.as = sizes->as;
    1380         2229 :   expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    1381         2229 :   expr2->value.op.op2->ref->u.ar.dimen = 1;
    1382         2229 :   expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1383         2229 :   expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
    1384         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
    1385         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
    1386         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    1387         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
    1388         2229 :         = gfc_lval_expr_from_sym (idx2);
    1389         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
    1390         2229 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1391         2229 :   expr2->value.op.op2->ref->u.ar.start[0]->ts
    1392         2229 :         = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
    1393         2229 :   expr2->ts = idx->ts;
    1394         2229 :   expr2->where = gfc_current_locus;
    1395              : 
    1396              :   /* ... * strides(idx2).  */
    1397         2229 :   expr = gfc_get_expr ();
    1398         2229 :   expr->expr_type = EXPR_OP;
    1399         2229 :   expr->value.op.op = INTRINSIC_TIMES;
    1400         2229 :   expr->value.op.op1 = expr2;
    1401         2229 :   expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
    1402         2229 :   expr->value.op.op2->ref = gfc_get_ref ();
    1403         2229 :   expr->value.op.op2->ref->type = REF_ARRAY;
    1404         2229 :   expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    1405         2229 :   expr->value.op.op2->ref->u.ar.dimen = 1;
    1406         2229 :   expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1407         2229 :   expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
    1408         2229 :   expr->value.op.op2->ref->u.ar.as = strides->as;
    1409         2229 :   expr->ts = idx->ts;
    1410         2229 :   expr->where = gfc_current_locus;
    1411              : 
    1412              :   /* offset = offset + ...  */
    1413         2229 :   block->block->next = gfc_get_code (EXEC_ASSIGN);
    1414         2229 :   block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
    1415         2229 :   block->block->next->expr2 = gfc_get_expr ();
    1416         2229 :   block->block->next->expr2->expr_type = EXPR_OP;
    1417         2229 :   block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
    1418         2229 :   block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
    1419         2229 :   block->block->next->expr2->value.op.op2 = expr;
    1420         2229 :   block->block->next->expr2->ts = idx->ts;
    1421         2229 :   block->block->next->expr2->where = gfc_current_locus;
    1422              : 
    1423              :   /* After the loop:  offset = offset * byte_stride.  */
    1424         2229 :   block->next = gfc_get_code (EXEC_ASSIGN);
    1425         2229 :   block = block->next;
    1426         2229 :   block->expr1 = gfc_lval_expr_from_sym (offset);
    1427         2229 :   block->expr2 = gfc_get_expr ();
    1428         2229 :   block->expr2->expr_type = EXPR_OP;
    1429         2229 :   block->expr2->value.op.op = INTRINSIC_TIMES;
    1430         2229 :   block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
    1431         2229 :   block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
    1432         2229 :   block->expr2->ts = block->expr2->value.op.op1->ts;
    1433         2229 :   block->expr2->where = gfc_current_locus;
    1434         2229 :   return block;
    1435              : }
    1436              : 
    1437              : 
    1438              : /* Insert code of the following form:
    1439              : 
    1440              :    block
    1441              :      integer(c_intptr_t) :: i
    1442              : 
    1443              :      if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
    1444              :           && (is_contiguous || !final_rank3->attr.contiguous
    1445              :               || final_rank3->as->type != AS_ASSUMED_SHAPE))
    1446              :          || 0 == STORAGE_SIZE (array)) then
    1447              :        call final_rank3 (array)
    1448              :      else
    1449              :        block
    1450              :          integer(c_intptr_t) :: offset, j
    1451              :          type(t) :: tmp(shape (array))
    1452              : 
    1453              :          do i = 0, size (array)-1
    1454              :            offset = obtain_offset(i, strides, sizes, byte_stride)
    1455              :            addr = transfer (c_loc (array), addr) + offset
    1456              :            call c_f_pointer (transfer (addr, cptr), ptr)
    1457              : 
    1458              :            addr = transfer (c_loc (tmp), addr)
    1459              :                             + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
    1460              :            call c_f_pointer (transfer (addr, cptr), ptr2)
    1461              :            ptr2 = ptr
    1462              :          end do
    1463              :          call final_rank3 (tmp)
    1464              :        end block
    1465              :      end if
    1466              :    block  */
    1467              : 
    1468              : static void
    1469          120 : finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
    1470              :                               gfc_symbol *array, gfc_symbol *byte_stride,
    1471              :                               gfc_symbol *idx, gfc_symbol *ptr,
    1472              :                               gfc_symbol *nelem,
    1473              :                               gfc_symbol *strides, gfc_symbol *sizes,
    1474              :                               gfc_symbol *idx2, gfc_symbol *offset,
    1475              :                               gfc_symbol *is_contiguous, gfc_expr *rank,
    1476              :                               gfc_namespace *sub_ns)
    1477              : {
    1478          120 :   gfc_symbol *tmp_array, *ptr2;
    1479          120 :   gfc_expr *size_expr, *offset2, *expr;
    1480          120 :   gfc_namespace *ns;
    1481          120 :   gfc_iterator *iter;
    1482          120 :   gfc_code *block2;
    1483          120 :   int i;
    1484              : 
    1485          120 :   block->next = gfc_get_code (EXEC_IF);
    1486          120 :   block = block->next;
    1487              : 
    1488          120 :   block->block = gfc_get_code (EXEC_IF);
    1489          120 :   block = block->block;
    1490              : 
    1491              :   /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE.  */
    1492          120 :   size_expr = gfc_get_expr ();
    1493          120 :   size_expr->where = gfc_current_locus;
    1494          120 :   size_expr->expr_type = EXPR_OP;
    1495          120 :   size_expr->value.op.op = INTRINSIC_DIVIDE;
    1496              : 
    1497              :   /* STORAGE_SIZE (array,kind=c_intptr_t).  */
    1498          120 :   size_expr->value.op.op1
    1499          120 :         = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
    1500              :                                     "storage_size", gfc_current_locus, 2,
    1501              :                                     gfc_lval_expr_from_sym (array),
    1502              :                                     gfc_get_int_expr (gfc_index_integer_kind,
    1503              :                                                       NULL, 0));
    1504              : 
    1505              :   /* NUMERIC_STORAGE_SIZE.  */
    1506          120 :   size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
    1507              :                                               gfc_character_storage_size);
    1508          120 :   size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
    1509          120 :   size_expr->ts = size_expr->value.op.op1->ts;
    1510              : 
    1511              :   /* IF condition: (stride == size_expr
    1512              :                     && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
    1513              :                         || is_contiguous)
    1514              :                    || 0 == size_expr.  */
    1515          120 :   block->expr1 = gfc_get_expr ();
    1516          120 :   block->expr1->ts.type = BT_LOGICAL;
    1517          120 :   block->expr1->ts.kind = gfc_default_logical_kind;
    1518          120 :   block->expr1->expr_type = EXPR_OP;
    1519          120 :   block->expr1->where = gfc_current_locus;
    1520              : 
    1521          120 :   block->expr1->value.op.op = INTRINSIC_OR;
    1522              : 
    1523              :   /* byte_stride == size_expr */
    1524          120 :   expr = gfc_get_expr ();
    1525          120 :   expr->ts.type = BT_LOGICAL;
    1526          120 :   expr->ts.kind = gfc_default_logical_kind;
    1527          120 :   expr->expr_type = EXPR_OP;
    1528          120 :   expr->where = gfc_current_locus;
    1529          120 :   expr->value.op.op = INTRINSIC_EQ;
    1530          120 :   expr->value.op.op1
    1531          120 :         = gfc_lval_expr_from_sym (byte_stride);
    1532          120 :   expr->value.op.op2 = size_expr;
    1533              : 
    1534              :   /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
    1535              :      add is_contiguous check.  */
    1536              : 
    1537          120 :   if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
    1538          100 :       || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
    1539              :     {
    1540           26 :       gfc_expr *expr2;
    1541           26 :       expr2 = gfc_get_expr ();
    1542           26 :       expr2->ts.type = BT_LOGICAL;
    1543           26 :       expr2->ts.kind = gfc_default_logical_kind;
    1544           26 :       expr2->expr_type = EXPR_OP;
    1545           26 :       expr2->where = gfc_current_locus;
    1546           26 :       expr2->value.op.op = INTRINSIC_AND;
    1547           26 :       expr2->value.op.op1 = expr;
    1548           26 :       expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
    1549           26 :       expr = expr2;
    1550              :     }
    1551              : 
    1552          120 :   block->expr1->value.op.op1 = expr;
    1553              : 
    1554              :   /* 0 == size_expr */
    1555          120 :   block->expr1->value.op.op2 = gfc_get_expr ();
    1556          120 :   block->expr1->value.op.op2->ts.type = BT_LOGICAL;
    1557          120 :   block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
    1558          120 :   block->expr1->value.op.op2->expr_type = EXPR_OP;
    1559          120 :   block->expr1->value.op.op2->where = gfc_current_locus;
    1560          120 :   block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
    1561          240 :   block->expr1->value.op.op2->value.op.op1 =
    1562          120 :                         gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1563          120 :   block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
    1564              : 
    1565              :   /* IF body: call final subroutine.  */
    1566          120 :   block->next = gfc_get_code (EXEC_CALL);
    1567          120 :   block->next->symtree = fini->proc_tree;
    1568          120 :   block->next->resolved_sym = fini->proc_tree->n.sym;
    1569          120 :   block->next->ext.actual = gfc_get_actual_arglist ();
    1570          120 :   block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
    1571              : 
    1572              :   /* ELSE.  */
    1573              : 
    1574          120 :   block->block = gfc_get_code (EXEC_IF);
    1575          120 :   block = block->block;
    1576              : 
    1577              :   /* BLOCK ... END BLOCK.  */
    1578          120 :   block->next = gfc_get_code (EXEC_BLOCK);
    1579          120 :   block = block->next;
    1580              : 
    1581          120 :   ns = gfc_build_block_ns (sub_ns);
    1582          120 :   block->ext.block.ns = ns;
    1583          120 :   block->ext.block.assoc = NULL;
    1584              : 
    1585          120 :   gfc_get_symbol ("ptr2", ns, &ptr2);
    1586          120 :   ptr2->ts.type = BT_DERIVED;
    1587          120 :   ptr2->ts.u.derived = array->ts.u.derived;
    1588          120 :   ptr2->attr.flavor = FL_VARIABLE;
    1589          120 :   ptr2->attr.pointer = 1;
    1590          120 :   ptr2->attr.artificial = 1;
    1591          120 :   gfc_set_sym_referenced (ptr2);
    1592          120 :   gfc_commit_symbol (ptr2);
    1593              : 
    1594          120 :   gfc_get_symbol ("tmp_array", ns, &tmp_array);
    1595          120 :   tmp_array->ts.type = BT_DERIVED;
    1596          120 :   tmp_array->ts.u.derived = array->ts.u.derived;
    1597          120 :   tmp_array->attr.flavor = FL_VARIABLE;
    1598          120 :   tmp_array->attr.dimension = 1;
    1599          120 :   tmp_array->attr.artificial = 1;
    1600          120 :   tmp_array->as = gfc_get_array_spec();
    1601          120 :   tmp_array->attr.intent = INTENT_INOUT;
    1602          120 :   tmp_array->as->type = AS_EXPLICIT;
    1603          120 :   tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
    1604              : 
    1605          314 :   for (i = 0; i < tmp_array->as->rank; i++)
    1606              :     {
    1607          194 :       gfc_expr *shape_expr;
    1608          194 :       tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
    1609              :                                                   NULL, 1);
    1610              :       /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind).  */
    1611          194 :       shape_expr
    1612          388 :         = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
    1613              :                                     gfc_current_locus, 3,
    1614              :                                     gfc_lval_expr_from_sym (array),
    1615              :                                     gfc_get_int_expr (gfc_default_integer_kind,
    1616          194 :                                                       NULL, i+1),
    1617              :                                     gfc_get_int_expr (gfc_default_integer_kind,
    1618              :                                                       NULL,
    1619              :                                                       gfc_index_integer_kind));
    1620          194 :       shape_expr->ts.kind = gfc_index_integer_kind;
    1621          194 :       tmp_array->as->upper[i] = shape_expr;
    1622              :     }
    1623          120 :   gfc_set_sym_referenced (tmp_array);
    1624          120 :   gfc_commit_symbol (tmp_array);
    1625              : 
    1626              :   /* Create loop.  */
    1627          120 :   iter = gfc_get_iterator ();
    1628          120 :   iter->var = gfc_lval_expr_from_sym (idx);
    1629          120 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1630          120 :   iter->end = gfc_lval_expr_from_sym (nelem);
    1631          120 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1632              : 
    1633          120 :   block = gfc_get_code (EXEC_DO);
    1634          120 :   ns->code = block;
    1635          120 :   block->ext.iterator = iter;
    1636          120 :   block->block = gfc_get_code (EXEC_DO);
    1637              : 
    1638              :   /* Offset calculation for the new array: idx * size of type (in bytes).  */
    1639          120 :   offset2 = gfc_get_expr ();
    1640          120 :   offset2->expr_type = EXPR_OP;
    1641          120 :   offset2->where = gfc_current_locus;
    1642          120 :   offset2->value.op.op = INTRINSIC_TIMES;
    1643          120 :   offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
    1644          120 :   offset2->value.op.op2 = gfc_copy_expr (size_expr);
    1645          120 :   offset2->ts = byte_stride->ts;
    1646              : 
    1647              :   /* Offset calculation of "array".  */
    1648          240 :   block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
    1649          120 :                                     byte_stride, rank, block->block, sub_ns);
    1650              : 
    1651              :   /* Create code for
    1652              :      CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
    1653              :                        + idx * stride, c_ptr), ptr).  */
    1654          120 :   block2->next = finalization_scalarizer (array, ptr,
    1655              :                                           gfc_lval_expr_from_sym (offset),
    1656              :                                           sub_ns);
    1657          120 :   block2 = block2->next;
    1658          120 :   block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
    1659          120 :   block2 = block2->next;
    1660              : 
    1661              :   /* ptr2 = ptr.  */
    1662          120 :   block2->next = gfc_get_code (EXEC_ASSIGN);
    1663          120 :   block2 = block2->next;
    1664          120 :   block2->expr1 = gfc_lval_expr_from_sym (ptr2);
    1665          120 :   block2->expr2 = gfc_lval_expr_from_sym (ptr);
    1666              : 
    1667              :   /* Call now the user's final subroutine.  */
    1668          120 :   block->next  = gfc_get_code (EXEC_CALL);
    1669          120 :   block = block->next;
    1670          120 :   block->symtree = fini->proc_tree;
    1671          120 :   block->resolved_sym = fini->proc_tree->n.sym;
    1672          120 :   block->ext.actual = gfc_get_actual_arglist ();
    1673          120 :   block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
    1674              : 
    1675          120 :   if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
    1676           18 :     return;
    1677              : 
    1678              :   /* Copy back.  */
    1679              : 
    1680              :   /* Loop.  */
    1681          102 :   iter = gfc_get_iterator ();
    1682          102 :   iter->var = gfc_lval_expr_from_sym (idx);
    1683          102 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1684          102 :   iter->end = gfc_lval_expr_from_sym (nelem);
    1685          102 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1686              : 
    1687          102 :   block->next = gfc_get_code (EXEC_DO);
    1688          102 :   block = block->next;
    1689          102 :   block->ext.iterator = iter;
    1690          102 :   block->block = gfc_get_code (EXEC_DO);
    1691              : 
    1692              :   /* Offset calculation of "array".  */
    1693          102 :   block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
    1694              :                                     byte_stride, rank, block->block, sub_ns);
    1695              : 
    1696              :   /* Create code for
    1697              :      CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
    1698              :                        + offset, c_ptr), ptr).  */
    1699          102 :   block2->next = finalization_scalarizer (array, ptr,
    1700              :                                           gfc_lval_expr_from_sym (offset),
    1701              :                                           sub_ns);
    1702          102 :   block2 = block2->next;
    1703          102 :   block2->next = finalization_scalarizer (tmp_array, ptr2,
    1704              :                                           gfc_copy_expr (offset2), sub_ns);
    1705          102 :   block2 = block2->next;
    1706              : 
    1707              :   /* ptr = ptr2.  */
    1708          102 :   block2->next = gfc_get_code (EXEC_ASSIGN);
    1709          102 :   block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
    1710          102 :   block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
    1711              : }
    1712              : 
    1713              : 
    1714              : /* Generate the finalization/polymorphic freeing wrapper subroutine for the
    1715              :    derived type "derived". The function first calls the appropriate FINAL
    1716              :    subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
    1717              :    components (but not the inherited ones). Last, it calls the wrapper
    1718              :    subroutine of the parent. The generated wrapper procedure takes as argument
    1719              :    an assumed-rank array.
    1720              :    If neither allocatable components nor FINAL subroutines exists, the vtab
    1721              :    will contain a NULL pointer.
    1722              :    The generated function has the form
    1723              :      _final(assumed-rank array, stride, skip_corarray)
    1724              :    where the array has to be contiguous (except of the lowest dimension). The
    1725              :    stride (in bytes) is used to allow different sizes for ancestor types by
    1726              :    skipping over the additionally added components in the scalarizer. If
    1727              :    "fini_coarray" is false, coarray components are not finalized to allow for
    1728              :    the correct semantic with intrinsic assignment.  */
    1729              : 
    1730              : static void
    1731        10338 : generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
    1732              :                                const char *tname, gfc_component *vtab_final)
    1733              : {
    1734        10338 :   gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
    1735        10338 :   gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
    1736        10338 :   gfc_symbol *result = NULL;
    1737        10338 :   gfc_component *comp;
    1738        10338 :   gfc_namespace *sub_ns;
    1739        10338 :   gfc_code *last_code, *block;
    1740        10338 :   char *name;
    1741        10338 :   char *result_name;
    1742        10338 :   bool finalizable_comp = false;
    1743        10338 :   gfc_expr *ancestor_wrapper = NULL, *rank;
    1744        10338 :   gfc_iterator *iter;
    1745              : 
    1746        10338 :   if (derived->attr.unlimited_polymorphic || derived->error)
    1747              :     {
    1748          754 :       vtab_final->initializer = gfc_get_null_expr (NULL);
    1749         8093 :       return;
    1750              :     }
    1751              : 
    1752              :   /* Search for the ancestor's finalizers.  */
    1753         1334 :   if (derived->attr.extension && derived->components
    1754        10918 :       && (!derived->components->ts.u.derived->attr.abstract
    1755          304 :           || has_finalizer_component (derived)))
    1756              :     {
    1757         1030 :       gfc_symbol *vtab;
    1758         1030 :       gfc_component *comp;
    1759              : 
    1760         1030 :       vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
    1761         6180 :       for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
    1762         6180 :         if (comp->name[0] == '_' && comp->name[1] == 'f')
    1763              :           {
    1764         1030 :             ancestor_wrapper = comp->initializer;
    1765         1030 :             break;
    1766              :           }
    1767              :     }
    1768              : 
    1769              :   /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
    1770              :      components: Return a NULL() expression; we defer this a bit to have
    1771              :      an interface declaration.  */
    1772         1030 :   if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
    1773         9405 :       && !derived->attr.alloc_comp
    1774         7615 :       && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
    1775         8335 :       && !has_finalizer_component (derived))
    1776              :     {
    1777         7275 :       vtab_final->initializer = gfc_get_null_expr (NULL);
    1778         7275 :       gcc_assert (vtab_final->ts.interface == NULL);
    1779              :       return;
    1780              :     }
    1781              :   else
    1782              :     /* Check whether there are new allocatable components.  */
    1783         6130 :     for (comp = derived->components; comp; comp = comp->next)
    1784              :       {
    1785         3821 :         if (comp == derived->components && derived->attr.extension
    1786          344 :             && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    1787          179 :         continue;
    1788              : 
    1789         3642 :         finalizable_comp |= comp_is_finalizable (comp);
    1790              :       }
    1791              : 
    1792              :   /* If there is no new finalizer and no new allocatable, return with
    1793              :      an expr to the ancestor's one.  */
    1794         2309 :   if (!finalizable_comp
    1795          416 :       && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
    1796              :     {
    1797           64 :       gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
    1798              :                   && ancestor_wrapper->expr_type == EXPR_VARIABLE);
    1799           64 :       vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
    1800           64 :       vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
    1801           64 :       return;
    1802              :     }
    1803              : 
    1804              :   /* We now create a wrapper, which does the following:
    1805              :      1. Call the suitable finalization subroutine for this type
    1806              :      2. Loop over all noninherited allocatable components and noninherited
    1807              :         components with allocatable components and DEALLOCATE those; this will
    1808              :         take care of finalizers, coarray deregistering and allocatable
    1809              :         nested components.
    1810              :      3. Call the ancestor's finalizer.  */
    1811              : 
    1812              :   /* Declare the wrapper function; it takes an assumed-rank array
    1813              :      and a VALUE logical as arguments.  */
    1814              : 
    1815              :   /* Set up the namespace.  */
    1816         2245 :   sub_ns = gfc_get_namespace (ns, 0);
    1817         2245 :   sub_ns->sibling = ns->contained;
    1818         2245 :   ns->contained = sub_ns;
    1819         2245 :   sub_ns->resolved = 1;
    1820              : 
    1821              :   /* Set up the procedure symbol.  */
    1822         2245 :   name = xasprintf ("__final_%s", tname);
    1823         2245 :   gfc_get_symbol (name, sub_ns, &final);
    1824         2245 :   sub_ns->proc_name = final;
    1825         2245 :   final->attr.flavor = FL_PROCEDURE;
    1826         2245 :   final->attr.function = 1;
    1827         2245 :   final->attr.pure = 0;
    1828         2245 :   final->attr.recursive = 1;
    1829         2245 :   final->ts.type = BT_INTEGER;
    1830         2245 :   final->ts.kind = 4;
    1831         2245 :   final->attr.artificial = 1;
    1832         2245 :   final->attr.always_explicit = 1;
    1833         2245 :   final->attr.if_source = IFSRC_DECL;
    1834         2245 :   if (ns->proc_name->attr.flavor == FL_MODULE)
    1835         1898 :     final->module = ns->proc_name->name;
    1836              : 
    1837              :   /* Create a separate result symbol instead of using final->result = final.
    1838              :      Self-referencing result symbols (final->result = final) create a cycle
    1839              :      in the symbol structure that causes an ICE in gimplify_call_expr when
    1840              :      the finalizer wrapper is used as a procedure pointer initializer.  */
    1841         2245 :   result_name = xasprintf ("__result_%s", tname);
    1842         2245 :   if (gfc_get_symbol (result_name, sub_ns, &result) != 0)
    1843            0 :     gfc_internal_error ("Failed to create finalizer result symbol");
    1844         2245 :   free (result_name);
    1845              : 
    1846         2245 :   if (!gfc_add_flavor (&result->attr, FL_VARIABLE, result->name,
    1847              :                        &gfc_current_locus)
    1848         2245 :       || !gfc_add_result (&result->attr, result->name, &gfc_current_locus))
    1849            0 :     gfc_internal_error ("Failed to set finalizer result attributes");
    1850              : 
    1851         2245 :   result->ts = final->ts;
    1852         2245 :   result->attr.artificial = 1;
    1853         2245 :   gfc_set_sym_referenced (result);
    1854         2245 :   gfc_commit_symbol (result);
    1855         2245 :   final->result = result;
    1856         2245 :   gfc_set_sym_referenced (final);
    1857         2245 :   gfc_commit_symbol (final);
    1858              : 
    1859              :   /* Set up formal argument.  */
    1860         2245 :   gfc_get_symbol ("array", sub_ns, &array);
    1861         2245 :   array->ts.type = BT_DERIVED;
    1862         2245 :   array->ts.u.derived = derived;
    1863         2245 :   array->attr.flavor = FL_VARIABLE;
    1864         2245 :   array->attr.dummy = 1;
    1865         2245 :   array->attr.contiguous = 1;
    1866         2245 :   array->attr.dimension = 1;
    1867         2245 :   array->attr.artificial = 1;
    1868         2245 :   array->as = gfc_get_array_spec();
    1869         2245 :   array->as->type = AS_ASSUMED_RANK;
    1870         2245 :   array->as->rank = -1;
    1871         2245 :   array->attr.intent = INTENT_INOUT;
    1872         2245 :   gfc_set_sym_referenced (array);
    1873         2245 :   final->formal = gfc_get_formal_arglist ();
    1874         2245 :   final->formal->sym = array;
    1875         2245 :   gfc_commit_symbol (array);
    1876              : 
    1877              :   /* Set up formal argument.  */
    1878         2245 :   gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
    1879         2245 :   byte_stride->ts.type = BT_INTEGER;
    1880         2245 :   byte_stride->ts.kind = gfc_index_integer_kind;
    1881         2245 :   byte_stride->attr.flavor = FL_VARIABLE;
    1882         2245 :   byte_stride->attr.dummy = 1;
    1883         2245 :   byte_stride->attr.value = 1;
    1884         2245 :   byte_stride->attr.artificial = 1;
    1885         2245 :   gfc_set_sym_referenced (byte_stride);
    1886         2245 :   final->formal->next = gfc_get_formal_arglist ();
    1887         2245 :   final->formal->next->sym = byte_stride;
    1888         2245 :   gfc_commit_symbol (byte_stride);
    1889              : 
    1890              :   /* Set up formal argument.  */
    1891         2245 :   gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
    1892         2245 :   fini_coarray->ts.type = BT_LOGICAL;
    1893         2245 :   fini_coarray->ts.kind = 1;
    1894         2245 :   fini_coarray->attr.flavor = FL_VARIABLE;
    1895         2245 :   fini_coarray->attr.dummy = 1;
    1896         2245 :   fini_coarray->attr.value = 1;
    1897         2245 :   fini_coarray->attr.artificial = 1;
    1898         2245 :   gfc_set_sym_referenced (fini_coarray);
    1899         2245 :   final->formal->next->next = gfc_get_formal_arglist ();
    1900         2245 :   final->formal->next->next->sym = fini_coarray;
    1901         2245 :   gfc_commit_symbol (fini_coarray);
    1902              : 
    1903              :   /* Local variables.  */
    1904              : 
    1905         2245 :   gfc_get_symbol ("idx", sub_ns, &idx);
    1906         2245 :   idx->ts.type = BT_INTEGER;
    1907         2245 :   idx->ts.kind = gfc_index_integer_kind;
    1908         2245 :   idx->attr.flavor = FL_VARIABLE;
    1909         2245 :   idx->attr.artificial = 1;
    1910         2245 :   gfc_set_sym_referenced (idx);
    1911         2245 :   gfc_commit_symbol (idx);
    1912              : 
    1913         2245 :   gfc_get_symbol ("idx2", sub_ns, &idx2);
    1914         2245 :   idx2->ts.type = BT_INTEGER;
    1915         2245 :   idx2->ts.kind = gfc_index_integer_kind;
    1916         2245 :   idx2->attr.flavor = FL_VARIABLE;
    1917         2245 :   idx2->attr.artificial = 1;
    1918         2245 :   gfc_set_sym_referenced (idx2);
    1919         2245 :   gfc_commit_symbol (idx2);
    1920              : 
    1921         2245 :   gfc_get_symbol ("offset", sub_ns, &offset);
    1922         2245 :   offset->ts.type = BT_INTEGER;
    1923         2245 :   offset->ts.kind = gfc_index_integer_kind;
    1924         2245 :   offset->attr.flavor = FL_VARIABLE;
    1925         2245 :   offset->attr.artificial = 1;
    1926         2245 :   gfc_set_sym_referenced (offset);
    1927         2245 :   gfc_commit_symbol (offset);
    1928              : 
    1929              :   /* Create RANK expression.  */
    1930         2245 :   rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
    1931              :                                    gfc_current_locus, 1,
    1932              :                                    gfc_lval_expr_from_sym (array));
    1933         2245 :   if (rank->ts.kind != idx->ts.kind)
    1934         2245 :     gfc_convert_type_warn (rank, &idx->ts, 2, 0);
    1935              : 
    1936              :   /* Create is_contiguous variable.  */
    1937         2245 :   gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
    1938         2245 :   is_contiguous->ts.type = BT_LOGICAL;
    1939         2245 :   is_contiguous->ts.kind = gfc_default_logical_kind;
    1940         2245 :   is_contiguous->attr.flavor = FL_VARIABLE;
    1941         2245 :   is_contiguous->attr.artificial = 1;
    1942         2245 :   gfc_set_sym_referenced (is_contiguous);
    1943         2245 :   gfc_commit_symbol (is_contiguous);
    1944              : 
    1945              :   /* Create "sizes(0..rank)" variable, which contains the multiplied
    1946              :      up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
    1947              :      sizes(2) = sizes(1) * extent(dim=2) etc.  */
    1948         2245 :   gfc_get_symbol ("sizes", sub_ns, &sizes);
    1949         2245 :   sizes->ts.type = BT_INTEGER;
    1950         2245 :   sizes->ts.kind = gfc_index_integer_kind;
    1951         2245 :   sizes->attr.flavor = FL_VARIABLE;
    1952         2245 :   sizes->attr.dimension = 1;
    1953         2245 :   sizes->attr.artificial = 1;
    1954         2245 :   sizes->as = gfc_get_array_spec();
    1955         2245 :   sizes->attr.intent = INTENT_INOUT;
    1956         2245 :   sizes->as->type = AS_EXPLICIT;
    1957         2245 :   sizes->as->rank = 1;
    1958         2245 :   sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1959         2245 :   sizes->as->upper[0] = gfc_copy_expr (rank);
    1960         2245 :   gfc_set_sym_referenced (sizes);
    1961         2245 :   gfc_commit_symbol (sizes);
    1962              : 
    1963              :   /* Create "strides(1..rank)" variable, which contains the strides per
    1964              :      dimension.  */
    1965         2245 :   gfc_get_symbol ("strides", sub_ns, &strides);
    1966         2245 :   strides->ts.type = BT_INTEGER;
    1967         2245 :   strides->ts.kind = gfc_index_integer_kind;
    1968         2245 :   strides->attr.flavor = FL_VARIABLE;
    1969         2245 :   strides->attr.dimension = 1;
    1970         2245 :   strides->attr.artificial = 1;
    1971         2245 :   strides->as = gfc_get_array_spec();
    1972         2245 :   strides->attr.intent = INTENT_INOUT;
    1973         2245 :   strides->as->type = AS_EXPLICIT;
    1974         2245 :   strides->as->rank = 1;
    1975         2245 :   strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1976         2245 :   strides->as->upper[0] = gfc_copy_expr (rank);
    1977         2245 :   gfc_set_sym_referenced (strides);
    1978         2245 :   gfc_commit_symbol (strides);
    1979              : 
    1980              : 
    1981              :   /* Set return value to 0.  */
    1982         2245 :   last_code = gfc_get_code (EXEC_ASSIGN);
    1983         2245 :   last_code->expr1 = gfc_lval_expr_from_sym (result);
    1984         2245 :   last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
    1985         2245 :   sub_ns->code = last_code;
    1986              : 
    1987              :   /* Set:  is_contiguous = .true.  */
    1988         2245 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    1989         2245 :   last_code = last_code->next;
    1990         2245 :   last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
    1991         2245 :   last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
    1992              :                                            &gfc_current_locus, true);
    1993              : 
    1994              :   /* Set:  sizes(0) = 1.  */
    1995         2245 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    1996         2245 :   last_code = last_code->next;
    1997         2245 :   last_code->expr1 = gfc_lval_expr_from_sym (sizes);
    1998         2245 :   last_code->expr1->ref = gfc_get_ref ();
    1999         2245 :   last_code->expr1->ref->type = REF_ARRAY;
    2000         2245 :   last_code->expr1->ref->u.ar.type = AR_ELEMENT;
    2001         2245 :   last_code->expr1->ref->u.ar.dimen = 1;
    2002         2245 :   last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2003         2245 :   last_code->expr1->ref->u.ar.start[0]
    2004         2245 :                 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2005         2245 :   last_code->expr1->ref->u.ar.as = sizes->as;
    2006         2245 :   last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
    2007              : 
    2008              :   /* Create:
    2009              :      DO idx = 1, rank
    2010              :        strides(idx) = _F._stride (array, dim=idx)
    2011              :        sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
    2012              :        if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
    2013              :      END DO.  */
    2014              : 
    2015              :   /* Create loop.  */
    2016         2245 :   iter = gfc_get_iterator ();
    2017         2245 :   iter->var = gfc_lval_expr_from_sym (idx);
    2018         2245 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2019         2245 :   iter->end = gfc_copy_expr (rank);
    2020         2245 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2021         2245 :   last_code->next = gfc_get_code (EXEC_DO);
    2022         2245 :   last_code = last_code->next;
    2023         2245 :   last_code->ext.iterator = iter;
    2024         2245 :   last_code->block = gfc_get_code (EXEC_DO);
    2025              : 
    2026              :   /* strides(idx) = _F._stride(array,dim=idx).  */
    2027         2245 :   last_code->block->next = gfc_get_code (EXEC_ASSIGN);
    2028         2245 :   block = last_code->block->next;
    2029              : 
    2030         2245 :   block->expr1 = gfc_lval_expr_from_sym (strides);
    2031         2245 :   block->expr1->ref = gfc_get_ref ();
    2032         2245 :   block->expr1->ref->type = REF_ARRAY;
    2033         2245 :   block->expr1->ref->u.ar.type = AR_ELEMENT;
    2034         2245 :   block->expr1->ref->u.ar.dimen = 1;
    2035         2245 :   block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2036         2245 :   block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2037         2245 :   block->expr1->ref->u.ar.as = strides->as;
    2038              : 
    2039         2245 :   block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
    2040              :                                            gfc_current_locus, 2,
    2041              :                                            gfc_lval_expr_from_sym (array),
    2042              :                                            gfc_lval_expr_from_sym (idx));
    2043              : 
    2044              :   /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind).  */
    2045         2245 :   block->next = gfc_get_code (EXEC_ASSIGN);
    2046         2245 :   block = block->next;
    2047              : 
    2048              :   /* sizes(idx) = ...  */
    2049         2245 :   block->expr1 = gfc_lval_expr_from_sym (sizes);
    2050         2245 :   block->expr1->ref = gfc_get_ref ();
    2051         2245 :   block->expr1->ref->type = REF_ARRAY;
    2052         2245 :   block->expr1->ref->u.ar.type = AR_ELEMENT;
    2053         2245 :   block->expr1->ref->u.ar.dimen = 1;
    2054         2245 :   block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2055         2245 :   block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2056         2245 :   block->expr1->ref->u.ar.as = sizes->as;
    2057              : 
    2058         2245 :   block->expr2 = gfc_get_expr ();
    2059         2245 :   block->expr2->expr_type = EXPR_OP;
    2060         2245 :   block->expr2->value.op.op = INTRINSIC_TIMES;
    2061         2245 :   block->expr2->where = gfc_current_locus;
    2062              : 
    2063              :   /* sizes(idx-1).  */
    2064         2245 :   block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
    2065         2245 :   block->expr2->value.op.op1->ref = gfc_get_ref ();
    2066         2245 :   block->expr2->value.op.op1->ref->type = REF_ARRAY;
    2067         2245 :   block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
    2068         2245 :   block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2069         2245 :   block->expr2->value.op.op1->ref->u.ar.dimen = 1;
    2070         2245 :   block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2071         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
    2072         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
    2073         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
    2074         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    2075         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
    2076         2245 :         = gfc_lval_expr_from_sym (idx);
    2077         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
    2078         2245 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2079         2245 :   block->expr2->value.op.op1->ref->u.ar.start[0]->ts
    2080         2245 :         = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
    2081              : 
    2082              :   /* size(array, dim=idx, kind=index_kind).  */
    2083         4490 :   block->expr2->value.op.op2
    2084         2245 :         = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
    2085              :                                     gfc_current_locus, 3,
    2086              :                                     gfc_lval_expr_from_sym (array),
    2087              :                                     gfc_lval_expr_from_sym (idx),
    2088              :                                     gfc_get_int_expr (gfc_index_integer_kind,
    2089              :                                                       NULL,
    2090              :                                                       gfc_index_integer_kind));
    2091         2245 :   block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
    2092         2245 :   block->expr2->ts = idx->ts;
    2093              : 
    2094              :   /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false.  */
    2095         2245 :   block->next = gfc_get_code (EXEC_IF);
    2096         2245 :   block = block->next;
    2097              : 
    2098         2245 :   block->block = gfc_get_code (EXEC_IF);
    2099         2245 :   block = block->block;
    2100              : 
    2101              :   /* if condition: strides(idx) /= sizes(idx-1).  */
    2102         2245 :   block->expr1 = gfc_get_expr ();
    2103         2245 :   block->expr1->ts.type = BT_LOGICAL;
    2104         2245 :   block->expr1->ts.kind = gfc_default_logical_kind;
    2105         2245 :   block->expr1->expr_type = EXPR_OP;
    2106         2245 :   block->expr1->where = gfc_current_locus;
    2107         2245 :   block->expr1->value.op.op = INTRINSIC_NE;
    2108              : 
    2109         2245 :   block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
    2110         2245 :   block->expr1->value.op.op1->ref = gfc_get_ref ();
    2111         2245 :   block->expr1->value.op.op1->ref->type = REF_ARRAY;
    2112         2245 :   block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2113         2245 :   block->expr1->value.op.op1->ref->u.ar.dimen = 1;
    2114         2245 :   block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2115         2245 :   block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2116         2245 :   block->expr1->value.op.op1->ref->u.ar.as = strides->as;
    2117              : 
    2118         2245 :   block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
    2119         2245 :   block->expr1->value.op.op2->ref = gfc_get_ref ();
    2120         2245 :   block->expr1->value.op.op2->ref->type = REF_ARRAY;
    2121         2245 :   block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
    2122         2245 :   block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    2123         2245 :   block->expr1->value.op.op2->ref->u.ar.dimen = 1;
    2124         2245 :   block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2125         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
    2126         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
    2127         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
    2128         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    2129         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
    2130         2245 :         = gfc_lval_expr_from_sym (idx);
    2131         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
    2132         2245 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2133         2245 :   block->expr1->value.op.op2->ref->u.ar.start[0]->ts
    2134         2245 :         = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
    2135              : 
    2136              :   /* if body: is_contiguous = .false.  */
    2137         2245 :   block->next = gfc_get_code (EXEC_ASSIGN);
    2138         2245 :   block = block->next;
    2139         2245 :   block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
    2140         2245 :   block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
    2141              :                                        &gfc_current_locus, false);
    2142              : 
    2143              :   /* Obtain the size (number of elements) of "array" MINUS ONE,
    2144              :      which is used in the scalarization.  */
    2145         2245 :   gfc_get_symbol ("nelem", sub_ns, &nelem);
    2146         2245 :   nelem->ts.type = BT_INTEGER;
    2147         2245 :   nelem->ts.kind = gfc_index_integer_kind;
    2148         2245 :   nelem->attr.flavor = FL_VARIABLE;
    2149         2245 :   nelem->attr.artificial = 1;
    2150         2245 :   gfc_set_sym_referenced (nelem);
    2151         2245 :   gfc_commit_symbol (nelem);
    2152              : 
    2153              :   /* nelem = sizes (rank) - 1.  */
    2154         2245 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    2155         2245 :   last_code = last_code->next;
    2156              : 
    2157         2245 :   last_code->expr1 = gfc_lval_expr_from_sym (nelem);
    2158              : 
    2159         2245 :   last_code->expr2 = gfc_get_expr ();
    2160         2245 :   last_code->expr2->expr_type = EXPR_OP;
    2161         2245 :   last_code->expr2->value.op.op = INTRINSIC_MINUS;
    2162         2245 :   last_code->expr2->value.op.op2
    2163         2245 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2164         2245 :   last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
    2165         2245 :   last_code->expr2->where = gfc_current_locus;
    2166              : 
    2167         2245 :   last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
    2168         2245 :   last_code->expr2->value.op.op1->ref = gfc_get_ref ();
    2169         2245 :   last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
    2170         2245 :   last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2171         2245 :   last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
    2172         2245 :   last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2173         2245 :   last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
    2174         2245 :   last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
    2175              : 
    2176              :   /* Call final subroutines. We now generate code like:
    2177              :      use iso_c_binding
    2178              :      integer, pointer :: ptr
    2179              :      type(c_ptr) :: cptr
    2180              :      integer(c_intptr_t) :: i, addr
    2181              : 
    2182              :      select case (rank (array))
    2183              :        case (3)
    2184              :          ! If needed, the array is packed
    2185              :          call final_rank3 (array)
    2186              :        case default:
    2187              :          do i = 0, size (array)-1
    2188              :            addr = transfer (c_loc (array), addr) + i * stride
    2189              :            call c_f_pointer (transfer (addr, cptr), ptr)
    2190              :            call elemental_final (ptr)
    2191              :          end do
    2192              :      end select */
    2193              : 
    2194         2245 :   if (derived->f2k_derived && derived->f2k_derived->finalizers)
    2195              :     {
    2196          430 :       gfc_finalizer *fini, *fini_elem = NULL;
    2197              : 
    2198          430 :       gfc_get_symbol ("ptr1", sub_ns, &ptr);
    2199          430 :       ptr->ts.type = BT_DERIVED;
    2200          430 :       ptr->ts.u.derived = derived;
    2201          430 :       ptr->attr.flavor = FL_VARIABLE;
    2202          430 :       ptr->attr.pointer = 1;
    2203          430 :       ptr->attr.artificial = 1;
    2204          430 :       gfc_set_sym_referenced (ptr);
    2205          430 :       gfc_commit_symbol (ptr);
    2206              : 
    2207          430 :       fini = derived->f2k_derived->finalizers;
    2208              : 
    2209              :       /* Assumed rank finalizers can be called directly. The call takes care
    2210              :          of setting up the descriptor.  resolve_finalizers has already checked
    2211              :          that this is the only finalizer for this kind/type (F2018: C790).  */
    2212          430 :       if (fini->proc_tree && fini->proc_tree->n.sym->formal->sym->as
    2213          106 :           && fini->proc_tree->n.sym->formal->sym->as->type == AS_ASSUMED_RANK)
    2214              :         {
    2215            6 :           last_code->next = gfc_get_code (EXEC_CALL);
    2216            6 :           last_code->next->symtree = fini->proc_tree;
    2217            6 :           last_code->next->resolved_sym = fini->proc_tree->n.sym;
    2218            6 :           last_code->next->ext.actual = gfc_get_actual_arglist ();
    2219            6 :           last_code->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
    2220              : 
    2221            6 :           last_code = last_code->next;
    2222            6 :           goto finish_assumed_rank;
    2223              :         }
    2224              : 
    2225              :       /* SELECT CASE (RANK (array)).  */
    2226          424 :       last_code->next = gfc_get_code (EXEC_SELECT);
    2227          424 :       last_code = last_code->next;
    2228          424 :       last_code->expr1 = gfc_copy_expr (rank);
    2229          424 :       block = NULL;
    2230              : 
    2231              : 
    2232          931 :       for (; fini; fini = fini->next)
    2233              :         {
    2234          507 :           gcc_assert (fini->proc_tree);   /* Should have been set in gfc_resolve_finalizers.  */
    2235          507 :           if (fini->proc_tree->n.sym->attr.elemental)
    2236              :             {
    2237          114 :               fini_elem = fini;
    2238          114 :               continue;
    2239              :             }
    2240              : 
    2241              :           /* CASE (fini_rank).  */
    2242          393 :           if (block)
    2243              :             {
    2244           70 :               block->block = gfc_get_code (EXEC_SELECT);
    2245           70 :               block = block->block;
    2246              :             }
    2247              :           else
    2248              :             {
    2249          323 :               block = gfc_get_code (EXEC_SELECT);
    2250          323 :               last_code->block = block;
    2251              :             }
    2252          393 :           block->ext.block.case_list = gfc_get_case ();
    2253          393 :           block->ext.block.case_list->where = gfc_current_locus;
    2254          393 :           if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
    2255          120 :             block->ext.block.case_list->low
    2256          120 :              = gfc_get_int_expr (gfc_default_integer_kind, NULL,
    2257          120 :                                  fini->proc_tree->n.sym->formal->sym->as->rank);
    2258              :           else
    2259          273 :             block->ext.block.case_list->low
    2260          273 :                 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
    2261          393 :           block->ext.block.case_list->high
    2262          393 :                 = gfc_copy_expr (block->ext.block.case_list->low);
    2263              : 
    2264              :           /* CALL fini_rank (array) - possibly with packing.  */
    2265          393 :           if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
    2266          120 :             finalizer_insert_packed_call (block, fini, array, byte_stride,
    2267              :                                           idx, ptr, nelem, strides,
    2268              :                                           sizes, idx2, offset, is_contiguous,
    2269              :                                           rank, sub_ns);
    2270              :           else
    2271              :             {
    2272          273 :               block->next = gfc_get_code (EXEC_CALL);
    2273          273 :               block->next->symtree = fini->proc_tree;
    2274          273 :               block->next->resolved_sym = fini->proc_tree->n.sym;
    2275          273 :               block->next->ext.actual = gfc_get_actual_arglist ();
    2276          273 :               block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
    2277              :             }
    2278              :         }
    2279              : 
    2280              :       /* Elemental call - scalarized.  */
    2281          424 :       if (fini_elem)
    2282              :         {
    2283              :           /* CASE DEFAULT.  */
    2284          114 :           if (block)
    2285              :             {
    2286           13 :               block->block = gfc_get_code (EXEC_SELECT);
    2287           13 :               block = block->block;
    2288              :             }
    2289              :           else
    2290              :             {
    2291          101 :               block = gfc_get_code (EXEC_SELECT);
    2292          101 :               last_code->block = block;
    2293              :             }
    2294          114 :           block->ext.block.case_list = gfc_get_case ();
    2295              : 
    2296              :           /* Create loop.  */
    2297          114 :           iter = gfc_get_iterator ();
    2298          114 :           iter->var = gfc_lval_expr_from_sym (idx);
    2299          114 :           iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2300          114 :           iter->end = gfc_lval_expr_from_sym (nelem);
    2301          114 :           iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2302          114 :           block->next = gfc_get_code (EXEC_DO);
    2303          114 :           block = block->next;
    2304          114 :           block->ext.iterator = iter;
    2305          114 :           block->block = gfc_get_code (EXEC_DO);
    2306              : 
    2307              :           /* Offset calculation.  */
    2308          114 :           block = finalization_get_offset (idx, idx2, offset, strides, sizes,
    2309              :                                            byte_stride, rank, block->block,
    2310              :                                            sub_ns);
    2311              : 
    2312              :           /* Create code for
    2313              :              CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
    2314              :                                + offset, c_ptr), ptr).  */
    2315          114 :           block->next
    2316          114 :                 = finalization_scalarizer (array, ptr,
    2317              :                                            gfc_lval_expr_from_sym (offset),
    2318              :                                            sub_ns);
    2319          114 :           block = block->next;
    2320              : 
    2321              :           /* CALL final_elemental (array).  */
    2322          114 :           block->next = gfc_get_code (EXEC_CALL);
    2323          114 :           block = block->next;
    2324          114 :           block->symtree = fini_elem->proc_tree;
    2325          114 :           block->resolved_sym = fini_elem->proc_sym;
    2326          114 :           block->ext.actual = gfc_get_actual_arglist ();
    2327          114 :           block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
    2328              :         }
    2329              :     }
    2330              : 
    2331         1815 : finish_assumed_rank:
    2332              : 
    2333              :   /* Finalize and deallocate allocatable components. The same manual
    2334              :      scalarization is used as above.  */
    2335              : 
    2336         2245 :   if (finalizable_comp)
    2337              :     {
    2338         1893 :       gfc_symbol *stat;
    2339         1893 :       gfc_code *block = NULL;
    2340         1893 :       gfc_expr *ptr_expr;
    2341              : 
    2342         1893 :       if (!ptr)
    2343              :         {
    2344         1815 :           gfc_get_symbol ("ptr2", sub_ns, &ptr);
    2345         1815 :           ptr->ts.type = BT_DERIVED;
    2346         1815 :           ptr->ts.u.derived = derived;
    2347         1815 :           ptr->attr.flavor = FL_VARIABLE;
    2348         1815 :           ptr->attr.pointer = 1;
    2349         1815 :           ptr->attr.artificial = 1;
    2350         1815 :           gfc_set_sym_referenced (ptr);
    2351         1815 :           gfc_commit_symbol (ptr);
    2352              :         }
    2353              : 
    2354         1893 :       gfc_get_symbol ("ignore", sub_ns, &stat);
    2355         1893 :       stat->attr.flavor = FL_VARIABLE;
    2356         1893 :       stat->attr.artificial = 1;
    2357         1893 :       stat->ts.type = BT_INTEGER;
    2358         1893 :       stat->ts.kind = gfc_default_integer_kind;
    2359         1893 :       gfc_set_sym_referenced (stat);
    2360         1893 :       gfc_commit_symbol (stat);
    2361              : 
    2362              :       /* Create loop.  */
    2363         1893 :       iter = gfc_get_iterator ();
    2364         1893 :       iter->var = gfc_lval_expr_from_sym (idx);
    2365         1893 :       iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2366         1893 :       iter->end = gfc_lval_expr_from_sym (nelem);
    2367         1893 :       iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2368         1893 :       last_code->next = gfc_get_code (EXEC_DO);
    2369         1893 :       last_code = last_code->next;
    2370         1893 :       last_code->ext.iterator = iter;
    2371         1893 :       last_code->block = gfc_get_code (EXEC_DO);
    2372              : 
    2373              :       /* Offset calculation.  */
    2374         1893 :       block = finalization_get_offset (idx, idx2, offset, strides, sizes,
    2375              :                                        byte_stride, rank, last_code->block,
    2376              :                                        sub_ns);
    2377              : 
    2378              :       /* Create code for
    2379              :          CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
    2380              :                            + idx * stride, c_ptr), ptr).  */
    2381         1893 :       block->next = finalization_scalarizer (array, ptr,
    2382              :                                              gfc_lval_expr_from_sym(offset),
    2383              :                                              sub_ns);
    2384         1893 :       block = block->next;
    2385              : 
    2386         1893 :       ptr_expr = gfc_lval_expr_from_sym (ptr);
    2387         5190 :       for (comp = derived->components; comp; comp = comp->next)
    2388              :         {
    2389         3297 :           if (comp == derived->components && derived->attr.extension
    2390          213 :               && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    2391           54 :             continue;
    2392              : 
    2393         3243 :           finalize_component (ptr_expr, derived, comp, stat, fini_coarray,
    2394              :                               &block, sub_ns);
    2395         3243 :           if (!last_code->block->next)
    2396            0 :             last_code->block->next = block;
    2397              :         }
    2398              : 
    2399              :     }
    2400              : 
    2401              :   /* Call the finalizer of the ancestor.  */
    2402         2245 :   if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    2403              :     {
    2404          115 :       last_code->next = gfc_get_code (EXEC_CALL);
    2405          115 :       last_code = last_code->next;
    2406          115 :       last_code->symtree = ancestor_wrapper->symtree;
    2407          115 :       last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
    2408              : 
    2409          115 :       last_code->ext.actual = gfc_get_actual_arglist ();
    2410          115 :       last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
    2411          115 :       last_code->ext.actual->next = gfc_get_actual_arglist ();
    2412          115 :       last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
    2413          115 :       last_code->ext.actual->next->next = gfc_get_actual_arglist ();
    2414          115 :       last_code->ext.actual->next->next->expr
    2415          115 :                         = gfc_lval_expr_from_sym (fini_coarray);
    2416              :     }
    2417              : 
    2418         2245 :   gfc_free_expr (rank);
    2419         2245 :   vtab_final->initializer = gfc_lval_expr_from_sym (final);
    2420         2245 :   vtab_final->ts.interface = final;
    2421         2245 :   free (name);
    2422              : }
    2423              : 
    2424              : 
    2425              : /* Add procedure pointers for all type-bound procedures to a vtab.  */
    2426              : 
    2427              : static void
    2428        11039 : add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
    2429              : {
    2430        11039 :   gfc_symbol* super_type;
    2431              : 
    2432        11039 :   super_type = gfc_get_derived_super_type (derived);
    2433              : 
    2434        11039 :   if (super_type && (super_type != derived))
    2435              :     {
    2436              :       /* Make sure that the PPCs appear in the same order as in the parent.  */
    2437         1454 :       copy_vtab_proc_comps (super_type, vtype);
    2438              :       /* Only needed to get the PPC initializers right.  */
    2439         1454 :       add_procs_to_declared_vtab (super_type, vtype);
    2440              :     }
    2441              : 
    2442        11039 :   if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
    2443         2270 :     add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
    2444              : 
    2445        11039 :   if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
    2446           30 :     add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
    2447        11039 : }
    2448              : 
    2449              : 
    2450              : /* Find or generate the symbol for a derived type's vtab.  */
    2451              : 
    2452              : gfc_symbol *
    2453        78621 : gfc_find_derived_vtab (gfc_symbol *derived)
    2454              : {
    2455        78621 :   gfc_namespace *ns;
    2456        78621 :   gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
    2457        78621 :   gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
    2458        78621 :   gfc_gsymbol *gsym = NULL;
    2459        78621 :   gfc_symbol *dealloc = NULL, *arg = NULL;
    2460              : 
    2461        78621 :   if (derived->attr.pdt_template)
    2462              :     return NULL;
    2463              : 
    2464              :   /* Find the top-level namespace.  */
    2465        88194 :   for (ns = gfc_current_ns; ns; ns = ns->parent)
    2466        88194 :     if (!ns->parent)
    2467              :       break;
    2468              : 
    2469              :   /* If the type is a class container, use the underlying derived type.  */
    2470        78595 :   if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
    2471        10239 :     derived = gfc_get_derived_super_type (derived);
    2472              : 
    2473        10239 :   if (!derived)
    2474              :     return NULL;
    2475              : 
    2476        78595 :   if (!derived->name)
    2477              :     return NULL;
    2478              : 
    2479              :   /* Find the gsymbol for the module of use associated derived types.  */
    2480        78595 :   if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
    2481        35805 :        && !derived->attr.vtype && !derived->attr.is_class)
    2482        35805 :     gsym =  gfc_find_gsymbol (gfc_gsym_root, derived->module);
    2483              :   else
    2484              :     gsym = NULL;
    2485              : 
    2486              :   /* Work in the gsymbol namespace if the top-level namespace is a module.
    2487              :      This ensures that the vtable is unique, which is required since we use
    2488              :      its address in SELECT TYPE.  */
    2489        35805 :   if (gsym && gsym->ns && ns && ns->proc_name
    2490        27311 :       && ns->proc_name->attr.flavor == FL_MODULE)
    2491              :     ns = gsym->ns;
    2492              : 
    2493        56503 :   if (ns)
    2494              :     {
    2495        78595 :       char tname[GFC_MAX_SYMBOL_LEN+1];
    2496        78595 :       char *name;
    2497              : 
    2498        78595 :       get_unique_hashed_string (tname, derived);
    2499        78595 :       name = xasprintf ("__vtab_%s", tname);
    2500              : 
    2501              :       /* Look for the vtab symbol in various namespaces.  */
    2502        78595 :       if (gsym && gsym->ns)
    2503              :         {
    2504        27311 :           gfc_find_symbol (name, gsym->ns, 0, &vtab);
    2505        27311 :           if (vtab)
    2506        26884 :             ns = gsym->ns;
    2507              :         }
    2508        78595 :       if (vtab == NULL)
    2509        51711 :         gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
    2510        78595 :       if (vtab == NULL)
    2511        16319 :         gfc_find_symbol (name, ns, 0, &vtab);
    2512        78595 :       if (vtab == NULL)
    2513        10372 :         gfc_find_symbol (name, derived->ns, 0, &vtab);
    2514              : 
    2515        78595 :       if (vtab == NULL)
    2516              :         {
    2517        10342 :           gfc_get_symbol (name, ns, &vtab);
    2518        10342 :           vtab->ts.type = BT_DERIVED;
    2519        10342 :           if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
    2520              :                                &gfc_current_locus))
    2521            0 :             goto cleanup;
    2522        10342 :           vtab->attr.target = 1;
    2523        10342 :           vtab->attr.save = SAVE_IMPLICIT;
    2524        10342 :           vtab->attr.vtab = 1;
    2525        10342 :           vtab->attr.access = ACCESS_PUBLIC;
    2526        10342 :           vtab->attr.artificial = 1;
    2527        10342 :           gfc_set_sym_referenced (vtab);
    2528        10342 :           free (name);
    2529        10342 :           name = xasprintf ("__vtype_%s", tname);
    2530              : 
    2531        10342 :           gfc_find_symbol (name, ns, 0, &vtype);
    2532        10342 :           if (vtype == NULL)
    2533              :             {
    2534        10342 :               gfc_component *c;
    2535        10342 :               gfc_symbol *parent = NULL, *parent_vtab = NULL;
    2536              : 
    2537        10342 :               gfc_get_symbol (name, ns, &vtype);
    2538        10342 :               if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
    2539              :                                    &gfc_current_locus))
    2540            0 :                 goto cleanup;
    2541        10342 :               vtype->attr.access = ACCESS_PUBLIC;
    2542        10342 :               vtype->attr.vtype = 1;
    2543        10342 :               gfc_set_sym_referenced (vtype);
    2544              : 
    2545              :               /* Add component '_hash'.  */
    2546        10342 :               if (!gfc_add_component (vtype, "_hash", &c))
    2547            0 :                 goto cleanup;
    2548        10342 :               c->ts.type = BT_INTEGER;
    2549        10342 :               c->ts.kind = 4;
    2550        10342 :               c->attr.access = ACCESS_PRIVATE;
    2551        20684 :               c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
    2552        10342 :                                                  NULL, derived->hash_value);
    2553              : 
    2554              :               /* Add component '_size'.  */
    2555        10342 :               if (!gfc_add_component (vtype, "_size", &c))
    2556            0 :                 goto cleanup;
    2557        10342 :               c->ts.type = BT_INTEGER;
    2558        10342 :               c->ts.kind = gfc_size_kind;
    2559        10342 :               c->attr.access = ACCESS_PRIVATE;
    2560              :               /* Remember the derived type in ts.u.derived,
    2561              :                  so that the correct initializer can be set later on
    2562              :                  (in gfc_conv_structure).  */
    2563        10342 :               c->ts.u.derived = derived;
    2564        10342 :               c->initializer = gfc_get_int_expr (gfc_size_kind,
    2565              :                                                  NULL, 0);
    2566              : 
    2567              :               /* Add component _extends.  */
    2568        10342 :               if (!gfc_add_component (vtype, "_extends", &c))
    2569            0 :                 goto cleanup;
    2570        10342 :               c->attr.pointer = 1;
    2571        10342 :               c->attr.access = ACCESS_PRIVATE;
    2572        10342 :               if (!derived->attr.unlimited_polymorphic)
    2573         9589 :                 parent = gfc_get_derived_super_type (derived);
    2574              :               else
    2575              :                 parent = NULL;
    2576              : 
    2577         9589 :               if (parent)
    2578              :                 {
    2579         1334 :                   parent_vtab = gfc_find_derived_vtab (parent);
    2580         1334 :                   c->ts.type = BT_DERIVED;
    2581         1334 :                   c->ts.u.derived = parent_vtab->ts.u.derived;
    2582         1334 :                   c->initializer = gfc_get_expr ();
    2583         1334 :                   c->initializer->expr_type = EXPR_VARIABLE;
    2584         1334 :                   gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
    2585              :                                      0, &c->initializer->symtree);
    2586              :                 }
    2587              :               else
    2588              :                 {
    2589         9008 :                   c->ts.type = BT_DERIVED;
    2590         9008 :                   c->ts.u.derived = vtype;
    2591         9008 :                   c->initializer = gfc_get_null_expr (NULL);
    2592              :                 }
    2593              : 
    2594        10342 :               if (!derived->attr.unlimited_polymorphic
    2595         9589 :                   && derived->components == NULL
    2596         1080 :                   && !derived->attr.zero_comp)
    2597              :                 {
    2598              :                   /* At this point an error must have occurred.
    2599              :                      Prevent further errors on the vtype components.  */
    2600            4 :                   found_sym = vtab;
    2601            4 :                   goto have_vtype;
    2602              :                 }
    2603              : 
    2604              :               /* Add component _def_init.  */
    2605        10338 :               if (!gfc_add_component (vtype, "_def_init", &c))
    2606            0 :                 goto cleanup;
    2607        10338 :               c->attr.pointer = 1;
    2608        10338 :               c->attr.artificial = 1;
    2609        10338 :               c->attr.access = ACCESS_PRIVATE;
    2610        10338 :               c->ts.type = BT_DERIVED;
    2611        10338 :               c->ts.u.derived = derived;
    2612        10338 :               if (derived->attr.unlimited_polymorphic
    2613         9585 :                   || derived->attr.abstract)
    2614         1063 :                 c->initializer = gfc_get_null_expr (NULL);
    2615              :               else
    2616              :                 {
    2617              :                   /* Construct default initialization variable.  */
    2618         9275 :                   free (name);
    2619         9275 :                   name = xasprintf ("__def_init_%s", tname);
    2620         9275 :                   gfc_get_symbol (name, ns, &def_init);
    2621         9275 :                   def_init->attr.target = 1;
    2622         9275 :                   def_init->attr.artificial = 1;
    2623         9275 :                   def_init->attr.save = SAVE_IMPLICIT;
    2624         9275 :                   def_init->attr.access = ACCESS_PUBLIC;
    2625         9275 :                   def_init->attr.flavor = FL_VARIABLE;
    2626         9275 :                   gfc_set_sym_referenced (def_init);
    2627         9275 :                   def_init->ts.type = BT_DERIVED;
    2628         9275 :                   def_init->ts.u.derived = derived;
    2629         9275 :                   def_init->value = gfc_default_initializer (&def_init->ts);
    2630              : 
    2631         9275 :                   c->initializer = gfc_lval_expr_from_sym (def_init);
    2632              :                 }
    2633              : 
    2634              :               /* Add component _copy.  */
    2635        10338 :               if (!gfc_add_component (vtype, "_copy", &c))
    2636            0 :                 goto cleanup;
    2637        10338 :               c->attr.proc_pointer = 1;
    2638        10338 :               c->attr.access = ACCESS_PRIVATE;
    2639        10338 :               c->attr.artificial = 1;
    2640        10338 :               c->tb = XCNEW (gfc_typebound_proc);
    2641        10338 :               c->tb->ppc = 1;
    2642        10338 :               if (derived->attr.unlimited_polymorphic
    2643         9585 :                   || derived->attr.abstract)
    2644         1063 :                 c->initializer = gfc_get_null_expr (NULL);
    2645              :               else
    2646              :                 {
    2647              :                   /* Set up namespace.  */
    2648         9275 :                   gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
    2649         9275 :                   sub_ns->sibling = ns->contained;
    2650         9275 :                   ns->contained = sub_ns;
    2651         9275 :                   sub_ns->resolved = 1;
    2652              :                   /* Set up procedure symbol.  */
    2653         9275 :                   free (name);
    2654         9275 :                   name = xasprintf ("__copy_%s", tname);
    2655         9275 :                   gfc_get_symbol (name, sub_ns, &copy);
    2656         9275 :                   sub_ns->proc_name = copy;
    2657         9275 :                   copy->attr.flavor = FL_PROCEDURE;
    2658         9275 :                   copy->attr.subroutine = 1;
    2659         9275 :                   copy->attr.pure = 1;
    2660         9275 :                   copy->attr.artificial = 1;
    2661         9275 :                   copy->attr.if_source = IFSRC_DECL;
    2662              :                   /* This is elemental so that arrays are automatically
    2663              :                      treated correctly by the scalarizer.  */
    2664         9275 :                   copy->attr.elemental = 1;
    2665         9275 :                   if (ns->proc_name->attr.flavor == FL_MODULE)
    2666         7585 :                     copy->module = ns->proc_name->name;
    2667         9275 :                   gfc_set_sym_referenced (copy);
    2668              :                   /* Set up formal arguments.  */
    2669         9275 :                   gfc_get_symbol ("src", sub_ns, &src);
    2670         9275 :                   src->ts.type = BT_DERIVED;
    2671         9275 :                   src->ts.u.derived = derived;
    2672         9275 :                   src->attr.flavor = FL_VARIABLE;
    2673         9275 :                   src->attr.dummy = 1;
    2674         9275 :                   src->attr.artificial = 1;
    2675         9275 :                   src->attr.intent = INTENT_IN;
    2676         9275 :                   gfc_set_sym_referenced (src);
    2677         9275 :                   copy->formal = gfc_get_formal_arglist ();
    2678         9275 :                   copy->formal->sym = src;
    2679         9275 :                   gfc_get_symbol ("dst", sub_ns, &dst);
    2680         9275 :                   dst->ts.type = BT_DERIVED;
    2681         9275 :                   dst->ts.u.derived = derived;
    2682         9275 :                   dst->attr.flavor = FL_VARIABLE;
    2683         9275 :                   dst->attr.dummy = 1;
    2684         9275 :                   dst->attr.artificial = 1;
    2685         9275 :                   dst->attr.intent = INTENT_INOUT;
    2686         9275 :                   gfc_set_sym_referenced (dst);
    2687         9275 :                   copy->formal->next = gfc_get_formal_arglist ();
    2688         9275 :                   copy->formal->next->sym = dst;
    2689              :                   /* Set up code.  */
    2690         9275 :                   sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
    2691         9275 :                   sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
    2692         9275 :                   sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
    2693              :                   /* Set initializer.  */
    2694         9275 :                   c->initializer = gfc_lval_expr_from_sym (copy);
    2695         9275 :                   c->ts.interface = copy;
    2696              :                 }
    2697              : 
    2698              :               /* Add component _final, which contains a procedure pointer to
    2699              :                  a wrapper which handles both the freeing of allocatable
    2700              :                  components and the calls to finalization subroutines.
    2701              :                  Note: The actual wrapper function can only be generated
    2702              :                  at resolution time.  */
    2703        10338 :               if (!gfc_add_component (vtype, "_final", &c))
    2704            0 :                 goto cleanup;
    2705        10338 :               c->attr.proc_pointer = 1;
    2706        10338 :               c->attr.access = ACCESS_PRIVATE;
    2707        10338 :               c->attr.artificial = 1;
    2708        10338 :               c->tb = XCNEW (gfc_typebound_proc);
    2709        10338 :               c->tb->ppc = 1;
    2710        10338 :               generate_finalization_wrapper (derived, ns, tname, c);
    2711              : 
    2712              :               /* Add component _deallocate.  */
    2713        10338 :               if (!gfc_add_component (vtype, "_deallocate", &c))
    2714            0 :                 goto cleanup;
    2715        10338 :               c->attr.proc_pointer = 1;
    2716        10338 :               c->attr.access = ACCESS_PRIVATE;
    2717        10338 :               c->attr.artificial = 1;
    2718        10338 :               c->tb = XCNEW (gfc_typebound_proc);
    2719        10338 :               c->tb->ppc = 1;
    2720        10338 :               if (derived->attr.unlimited_polymorphic || derived->attr.abstract
    2721         9275 :                   || !derived->attr.recursive)
    2722        10083 :                 c->initializer = gfc_get_null_expr (NULL);
    2723              :               else
    2724              :                 {
    2725              :                   /* Set up namespace.  */
    2726          255 :                   gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
    2727              : 
    2728          255 :                   sub_ns->sibling = ns->contained;
    2729          255 :                   ns->contained = sub_ns;
    2730          255 :                   sub_ns->resolved = 1;
    2731              :                   /* Set up procedure symbol.  */
    2732          255 :                   free (name);
    2733          255 :                   name = xasprintf ("__deallocate_%s", tname);
    2734          255 :                   gfc_get_symbol (name, sub_ns, &dealloc);
    2735          255 :                   sub_ns->proc_name = dealloc;
    2736          255 :                   dealloc->attr.flavor = FL_PROCEDURE;
    2737          255 :                   dealloc->attr.subroutine = 1;
    2738          255 :                   dealloc->attr.pure = 1;
    2739          255 :                   dealloc->attr.artificial = 1;
    2740          255 :                   dealloc->attr.if_source = IFSRC_DECL;
    2741              : 
    2742          255 :                   if (ns->proc_name->attr.flavor == FL_MODULE)
    2743          173 :                     dealloc->module = ns->proc_name->name;
    2744          255 :                   gfc_set_sym_referenced (dealloc);
    2745              :                   /* Set up formal argument.  */
    2746          255 :                   gfc_get_symbol ("arg", sub_ns, &arg);
    2747          255 :                   arg->ts.type = BT_DERIVED;
    2748          255 :                   arg->ts.u.derived = derived;
    2749          255 :                   arg->attr.flavor = FL_VARIABLE;
    2750          255 :                   arg->attr.dummy = 1;
    2751          255 :                   arg->attr.artificial = 1;
    2752          255 :                   arg->attr.intent = INTENT_INOUT;
    2753          255 :                   arg->attr.dimension = 1;
    2754          255 :                   arg->attr.allocatable = 1;
    2755          255 :                   arg->as = gfc_get_array_spec();
    2756          255 :                   arg->as->type = AS_ASSUMED_SHAPE;
    2757          255 :                   arg->as->rank = 1;
    2758          255 :                   arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
    2759              :                                                         NULL, 1);
    2760          255 :                   gfc_set_sym_referenced (arg);
    2761          255 :                   dealloc->formal = gfc_get_formal_arglist ();
    2762          255 :                   dealloc->formal->sym = arg;
    2763              :                   /* Set up code.  */
    2764          255 :                   sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
    2765          255 :                   sub_ns->code->ext.alloc.list = gfc_get_alloc ();
    2766          255 :                   sub_ns->code->ext.alloc.list->expr
    2767          255 :                                 = gfc_lval_expr_from_sym (arg);
    2768              :                   /* Set initializer.  */
    2769          255 :                   c->initializer = gfc_lval_expr_from_sym (dealloc);
    2770          255 :                   c->ts.interface = dealloc;
    2771              :                 }
    2772              : 
    2773              :               /* Add procedure pointers for type-bound procedures.  */
    2774        10338 :               if (!derived->attr.unlimited_polymorphic)
    2775         9585 :                 add_procs_to_declared_vtab (derived, vtype);
    2776              :           }
    2777              : 
    2778            0 : have_vtype:
    2779        10342 :           vtab->ts.u.derived = vtype;
    2780        10342 :           vtab->value = gfc_default_initializer (&vtab->ts);
    2781              :         }
    2782        78595 :       free (name);
    2783              :     }
    2784              : 
    2785        78595 :   found_sym = vtab;
    2786              : 
    2787        78595 : cleanup:
    2788              :   /* It is unexpected to have some symbols added at resolution or code
    2789              :      generation time. We commit the changes in order to keep a clean state.  */
    2790        78595 :   if (found_sym)
    2791              :     {
    2792        78595 :       gfc_commit_symbol (vtab);
    2793        78595 :       if (vtype)
    2794        10342 :         gfc_commit_symbol (vtype);
    2795        78595 :       if (def_init)
    2796         9275 :         gfc_commit_symbol (def_init);
    2797        78595 :       if (copy)
    2798         9275 :         gfc_commit_symbol (copy);
    2799        78595 :       if (src)
    2800         9275 :         gfc_commit_symbol (src);
    2801        78595 :       if (dst)
    2802         9275 :         gfc_commit_symbol (dst);
    2803        78595 :       if (dealloc)
    2804          255 :         gfc_commit_symbol (dealloc);
    2805        78595 :       if (arg)
    2806          255 :         gfc_commit_symbol (arg);
    2807              :     }
    2808              :   else
    2809            0 :     gfc_undo_symbols ();
    2810              : 
    2811              :   return found_sym;
    2812              : }
    2813              : 
    2814              : 
    2815              : /* Check if a derived type is finalizable. That is the case if it
    2816              :    (1) has a FINAL subroutine or
    2817              :    (2) has a nonpointer nonallocatable component of finalizable type.
    2818              :    If it is finalizable, return an expression containing the
    2819              :    finalization wrapper.  */
    2820              : 
    2821              : bool
    2822       101713 : gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
    2823              : {
    2824       101713 :   gfc_symbol *vtab;
    2825       101713 :   gfc_component *c;
    2826              : 
    2827              :   /* (1) Check for FINAL subroutines.  */
    2828       101713 :   if (derived->f2k_derived && derived->f2k_derived->finalizers)
    2829         6615 :     goto yes;
    2830              : 
    2831              :   /* (2) Check for components of finalizable type.  */
    2832       245250 :   for (c = derived->components; c; c = c->next)
    2833       150702 :     if (c->ts.type == BT_DERIVED
    2834        26071 :         && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
    2835       158846 :         && gfc_is_finalizable (c->ts.u.derived, NULL))
    2836          550 :       goto yes;
    2837              : 
    2838              :   return false;
    2839              : 
    2840         7165 : yes:
    2841              :   /* Make sure vtab is generated.  */
    2842         7165 :   vtab = gfc_find_derived_vtab (derived);
    2843         7165 :   if (final_expr)
    2844              :     {
    2845              :       /* Return finalizer expression.  */
    2846          912 :       gfc_component *final;
    2847          912 :       final = vtab->ts.u.derived->components->next->next->next->next->next;
    2848          912 :       gcc_assert (strcmp (final->name, "_final") == 0);
    2849          912 :       gcc_assert (final->initializer
    2850              :                   && final->initializer->expr_type != EXPR_NULL);
    2851          912 :       *final_expr = final->initializer;
    2852              :     }
    2853              :   return true;
    2854              : }
    2855              : 
    2856              : 
    2857              : bool
    2858       516957 : gfc_may_be_finalized (gfc_typespec ts)
    2859              : {
    2860       516957 :   return (ts.type == BT_CLASS || (ts.type == BT_DERIVED
    2861        68928 :           && ts.u.derived && gfc_is_finalizable (ts.u.derived, NULL)));
    2862              : }
    2863              : 
    2864              : 
    2865              : /* Find (or generate) the symbol for an intrinsic type's vtab.  This is
    2866              :    needed to support unlimited polymorphism.  */
    2867              : 
    2868              : static gfc_symbol *
    2869         6782 : find_intrinsic_vtab (gfc_typespec *ts)
    2870              : {
    2871         6782 :   gfc_namespace *ns;
    2872         6782 :   gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
    2873         6782 :   gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
    2874              : 
    2875              :   /* Find the top-level namespace.  */
    2876         8664 :   for (ns = gfc_current_ns; ns; ns = ns->parent)
    2877         8664 :     if (!ns->parent)
    2878              :       break;
    2879              : 
    2880         6782 :   if (ns)
    2881              :     {
    2882         6782 :       char tname[GFC_MAX_SYMBOL_LEN+1];
    2883         6782 :       char *name;
    2884              : 
    2885              :       /* Encode all types as TYPENAME_KIND_ including especially character
    2886              :          arrays, whose length is now consistently stored in the _len component
    2887              :          of the class-variable.  */
    2888         6782 :       sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
    2889         6782 :       name = xasprintf ("__vtab_%s", tname);
    2890              : 
    2891              :       /* Look for the vtab symbol in the top-level namespace only.  */
    2892         6782 :       gfc_find_symbol (name, ns, 0, &vtab);
    2893              : 
    2894         6782 :       if (vtab == NULL)
    2895              :         {
    2896          930 :           gfc_get_symbol (name, ns, &vtab);
    2897          930 :           vtab->ts.type = BT_DERIVED;
    2898          930 :           if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
    2899              :                                &gfc_current_locus))
    2900            0 :             goto cleanup;
    2901          930 :           vtab->attr.target = 1;
    2902          930 :           vtab->attr.save = SAVE_IMPLICIT;
    2903          930 :           vtab->attr.vtab = 1;
    2904          930 :           vtab->attr.access = ACCESS_PUBLIC;
    2905          930 :           gfc_set_sym_referenced (vtab);
    2906          930 :           free (name);
    2907          930 :           name = xasprintf ("__vtype_%s", tname);
    2908              : 
    2909          930 :           gfc_find_symbol (name, ns, 0, &vtype);
    2910          930 :           if (vtype == NULL)
    2911              :             {
    2912          930 :               gfc_component *c;
    2913          930 :               int hash;
    2914          930 :               gfc_namespace *sub_ns;
    2915          930 :               gfc_namespace *contained;
    2916          930 :               gfc_expr *e;
    2917          930 :               size_t e_size;
    2918              : 
    2919          930 :               gfc_get_symbol (name, ns, &vtype);
    2920          930 :               if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
    2921              :                                    &gfc_current_locus))
    2922            0 :                 goto cleanup;
    2923          930 :               vtype->attr.access = ACCESS_PUBLIC;
    2924          930 :               vtype->attr.vtype = 1;
    2925          930 :               gfc_set_sym_referenced (vtype);
    2926              : 
    2927              :               /* Add component '_hash'.  */
    2928          930 :               if (!gfc_add_component (vtype, "_hash", &c))
    2929            0 :                 goto cleanup;
    2930          930 :               c->ts.type = BT_INTEGER;
    2931          930 :               c->ts.kind = 4;
    2932          930 :               c->attr.access = ACCESS_PRIVATE;
    2933          930 :               hash = gfc_intrinsic_hash_value (ts);
    2934          930 :               c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
    2935              :                                                  NULL, hash);
    2936              : 
    2937              :               /* Add component '_size'.  */
    2938          930 :               if (!gfc_add_component (vtype, "_size", &c))
    2939            0 :                 goto cleanup;
    2940          930 :               c->ts.type = BT_INTEGER;
    2941          930 :               c->ts.kind = gfc_size_kind;
    2942          930 :               c->attr.access = ACCESS_PRIVATE;
    2943              : 
    2944              :               /* Build a minimal expression to make use of
    2945              :                  target-memory.cc/gfc_element_size for 'size'.  Special handling
    2946              :                  for character arrays, that are not constant sized: to support
    2947              :                  len (str) * kind, only the kind information is stored in the
    2948              :                  vtab.  */
    2949          930 :               e = gfc_get_expr ();
    2950          930 :               e->ts = *ts;
    2951          930 :               e->expr_type = EXPR_VARIABLE;
    2952          930 :               if (ts->type == BT_CHARACTER)
    2953          263 :                 e_size = ts->kind;
    2954              :               else
    2955          667 :                 gfc_element_size (e, &e_size);
    2956          930 :               c->initializer = gfc_get_int_expr (gfc_size_kind,
    2957              :                                                  NULL,
    2958              :                                                  e_size);
    2959          930 :               gfc_free_expr (e);
    2960              : 
    2961              :               /* Add component _extends.  */
    2962          930 :               if (!gfc_add_component (vtype, "_extends", &c))
    2963            0 :                 goto cleanup;
    2964          930 :               c->attr.pointer = 1;
    2965          930 :               c->attr.access = ACCESS_PRIVATE;
    2966          930 :               c->ts.type = BT_VOID;
    2967          930 :               c->initializer = gfc_get_null_expr (NULL);
    2968              : 
    2969              :               /* Add component _def_init.  */
    2970          930 :               if (!gfc_add_component (vtype, "_def_init", &c))
    2971            0 :                 goto cleanup;
    2972          930 :               c->attr.pointer = 1;
    2973          930 :               c->attr.access = ACCESS_PRIVATE;
    2974          930 :               c->ts.type = BT_VOID;
    2975          930 :               c->initializer = gfc_get_null_expr (NULL);
    2976              : 
    2977              :               /* Add component _copy.  */
    2978          930 :               if (!gfc_add_component (vtype, "_copy", &c))
    2979            0 :                 goto cleanup;
    2980          930 :               c->attr.proc_pointer = 1;
    2981          930 :               c->attr.access = ACCESS_PRIVATE;
    2982          930 :               c->attr.artificial = 1;
    2983          930 :               c->tb = XCNEW (gfc_typebound_proc);
    2984          930 :               c->tb->ppc = 1;
    2985              : 
    2986          930 :               free (name);
    2987          930 :               if (ts->type != BT_CHARACTER)
    2988          667 :                 name = xasprintf ("__copy_%s", tname);
    2989              :               else
    2990              :                 {
    2991              :                   /* __copy is always the same for characters.
    2992              :                      Check to see if copy function already exists.  */
    2993          263 :                   name = xasprintf ("__copy_character_%d", ts->kind);
    2994          263 :                   contained = ns->contained;
    2995         1328 :                   for (; contained; contained = contained->sibling)
    2996         1065 :                     if (contained->proc_name
    2997         1065 :                         && strcmp (name, contained->proc_name->name) == 0)
    2998              :                       {
    2999            0 :                         copy = contained->proc_name;
    3000            0 :                         goto got_char_copy;
    3001              :                       }
    3002              :                 }
    3003              : 
    3004              :               /* Set up namespace.  */
    3005          930 :               sub_ns = gfc_get_namespace (ns, 0);
    3006          930 :               sub_ns->sibling = ns->contained;
    3007          930 :               ns->contained = sub_ns;
    3008          930 :               sub_ns->resolved = 1;
    3009              :               /* Set up procedure symbol.  */
    3010          930 :               gfc_get_symbol (name, sub_ns, &copy);
    3011          930 :               sub_ns->proc_name = copy;
    3012          930 :               copy->attr.flavor = FL_PROCEDURE;
    3013          930 :               copy->attr.subroutine = 1;
    3014          930 :               copy->attr.pure = 1;
    3015          930 :               copy->attr.if_source = IFSRC_DECL;
    3016              :               /* This is elemental so that arrays are automatically
    3017              :                  treated correctly by the scalarizer.  */
    3018          930 :               copy->attr.elemental = 1;
    3019          930 :               if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
    3020          204 :                 copy->module = ns->proc_name->name;
    3021          930 :               gfc_set_sym_referenced (copy);
    3022              :               /* Set up formal arguments.  */
    3023          930 :               gfc_get_symbol ("src", sub_ns, &src);
    3024          930 :               src->ts.type = ts->type;
    3025          930 :               src->ts.kind = ts->kind;
    3026          930 :               src->attr.flavor = FL_VARIABLE;
    3027          930 :               src->attr.dummy = 1;
    3028          930 :               src->attr.intent = INTENT_IN;
    3029          930 :               gfc_set_sym_referenced (src);
    3030          930 :               copy->formal = gfc_get_formal_arglist ();
    3031          930 :               copy->formal->sym = src;
    3032          930 :               gfc_get_symbol ("dst", sub_ns, &dst);
    3033          930 :               dst->ts.type = ts->type;
    3034          930 :               dst->ts.kind = ts->kind;
    3035          930 :               dst->attr.flavor = FL_VARIABLE;
    3036          930 :               dst->attr.dummy = 1;
    3037          930 :               dst->attr.intent = INTENT_INOUT;
    3038          930 :               gfc_set_sym_referenced (dst);
    3039          930 :               copy->formal->next = gfc_get_formal_arglist ();
    3040          930 :               copy->formal->next->sym = dst;
    3041              :               /* Set up code.  */
    3042          930 :               sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
    3043          930 :               sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
    3044          930 :               sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
    3045          930 :             got_char_copy:
    3046              :               /* Set initializer.  */
    3047          930 :               c->initializer = gfc_lval_expr_from_sym (copy);
    3048          930 :               c->ts.interface = copy;
    3049              : 
    3050              :               /* Add component _final.  */
    3051          930 :               if (!gfc_add_component (vtype, "_final", &c))
    3052            0 :                 goto cleanup;
    3053          930 :               c->attr.proc_pointer = 1;
    3054          930 :               c->attr.access = ACCESS_PRIVATE;
    3055          930 :               c->attr.artificial = 1;
    3056          930 :               c->tb = XCNEW (gfc_typebound_proc);
    3057          930 :               c->tb->ppc = 1;
    3058          930 :               c->initializer = gfc_get_null_expr (NULL);
    3059              :             }
    3060          930 :           vtab->ts.u.derived = vtype;
    3061          930 :           vtab->value = gfc_default_initializer (&vtab->ts);
    3062              :         }
    3063         6782 :       free (name);
    3064              :     }
    3065              : 
    3066         6782 :   found_sym = vtab;
    3067              : 
    3068         6782 : cleanup:
    3069              :   /* It is unexpected to have some symbols added at resolution or code
    3070              :      generation time. We commit the changes in order to keep a clean state.  */
    3071         6782 :   if (found_sym)
    3072              :     {
    3073         6782 :       gfc_commit_symbol (vtab);
    3074         6782 :       if (vtype)
    3075          930 :         gfc_commit_symbol (vtype);
    3076         6782 :       if (copy)
    3077          930 :         gfc_commit_symbol (copy);
    3078         6782 :       if (src)
    3079          930 :         gfc_commit_symbol (src);
    3080         6782 :       if (dst)
    3081          930 :         gfc_commit_symbol (dst);
    3082              :     }
    3083              :   else
    3084            0 :     gfc_undo_symbols ();
    3085              : 
    3086         6782 :   return found_sym;
    3087              : }
    3088              : 
    3089              : 
    3090              : /*  Find (or generate) a vtab for an arbitrary type (derived or intrinsic).  */
    3091              : 
    3092              : gfc_symbol *
    3093        19929 : gfc_find_vtab (gfc_typespec *ts)
    3094              : {
    3095        19929 :   switch (ts->type)
    3096              :     {
    3097              :     case BT_UNKNOWN:
    3098              :       return NULL;
    3099         7967 :     case BT_DERIVED:
    3100         7967 :       return gfc_find_derived_vtab (ts->u.derived);
    3101         5104 :     case BT_CLASS:
    3102         5104 :       if (ts->u.derived->attr.is_class
    3103         5100 :           && ts->u.derived->components
    3104         5100 :           && ts->u.derived->components->ts.u.derived)
    3105         5100 :         return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
    3106              :       else
    3107              :         return NULL;
    3108         6782 :     default:
    3109         6782 :       return find_intrinsic_vtab (ts);
    3110              :     }
    3111              : }
    3112              : 
    3113              : 
    3114              : /* General worker function to find either a type-bound procedure or a
    3115              :    type-bound user operator.  */
    3116              : 
    3117              : static gfc_symtree*
    3118       458808 : find_typebound_proc_uop (gfc_symbol* derived, bool* t,
    3119              :                          const char* name, bool noaccess, bool uop,
    3120              :                          locus* where)
    3121              : {
    3122       458808 :   gfc_symtree* res;
    3123       458808 :   gfc_symtree* root;
    3124              : 
    3125              :   /* Set default to failure.  */
    3126       458808 :   if (t)
    3127       439170 :     *t = false;
    3128              : 
    3129       458808 :   if (derived->f2k_derived)
    3130              :     /* Set correct symbol-root.  */
    3131       344338 :     root = (uop ? derived->f2k_derived->tb_uop_root
    3132              :                 : derived->f2k_derived->tb_sym_root);
    3133              :   else
    3134              :     return NULL;
    3135              : 
    3136              :   /* Try to find it in the current type's namespace.  */
    3137       344338 :   res = gfc_find_symtree (root, name);
    3138       344338 :   if (res && res->n.tb && !res->n.tb->error)
    3139              :     {
    3140              :       /* We found one.  */
    3141        10468 :       if (t)
    3142         5953 :         *t = true;
    3143              : 
    3144        10468 :       if (!noaccess && derived->attr.use_assoc
    3145         3347 :           && res->n.tb->access == ACCESS_PRIVATE)
    3146              :         {
    3147            3 :           if (where)
    3148            2 :             gfc_error ("%qs of %qs is PRIVATE at %L",
    3149              :                        name, derived->name, where);
    3150            3 :           if (t)
    3151            3 :             *t = false;
    3152              :         }
    3153              : 
    3154        10468 :       return res;
    3155              :     }
    3156              : 
    3157              :   /* Otherwise, recurse on parent type if derived is an extension.  */
    3158       333870 :   if (derived->attr.extension)
    3159              :     {
    3160        44405 :       gfc_symbol* super_type;
    3161        44405 :       super_type = gfc_get_derived_super_type (derived);
    3162        44405 :       gcc_assert (super_type);
    3163              : 
    3164        44405 :       return find_typebound_proc_uop (super_type, t, name,
    3165        44405 :                                       noaccess, uop, where);
    3166              :     }
    3167              : 
    3168              :   /* Nothing found.  */
    3169              :   return NULL;
    3170              : }
    3171              : 
    3172              : 
    3173              : /* Find a type-bound procedure or user operator by name for a derived-type
    3174              :    (looking recursively through the super-types).  */
    3175              : 
    3176              : gfc_symtree*
    3177       414217 : gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
    3178              :                          const char* name, bool noaccess, locus* where)
    3179              : {
    3180       414217 :   return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
    3181              : }
    3182              : 
    3183              : gfc_symtree*
    3184          186 : gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
    3185              :                             const char* name, bool noaccess, locus* where)
    3186              : {
    3187          186 :   return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
    3188              : }
    3189              : 
    3190              : 
    3191              : /* Find a type-bound intrinsic operator looking recursively through the
    3192              :    super-type hierarchy.  */
    3193              : 
    3194              : gfc_typebound_proc*
    3195        21977 : gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
    3196              :                                  gfc_intrinsic_op op, bool noaccess,
    3197              :                                  locus* where)
    3198              : {
    3199        21977 :   gfc_typebound_proc* res;
    3200              : 
    3201              :   /* Set default to failure.  */
    3202        21977 :   if (t)
    3203        21976 :     *t = false;
    3204              : 
    3205              :   /* Try to find it in the current type's namespace.  */
    3206        21977 :   if (derived->f2k_derived)
    3207        18064 :     res = derived->f2k_derived->tb_op[op];
    3208              :   else
    3209              :     res = NULL;
    3210              : 
    3211              :   /* Check access.  */
    3212        18064 :   if (res && !res->error)
    3213              :     {
    3214              :       /* We found one.  */
    3215          892 :       if (t)
    3216          891 :         *t = true;
    3217              : 
    3218          892 :       if (!noaccess && derived->attr.use_assoc
    3219          755 :           && res->access == ACCESS_PRIVATE)
    3220              :         {
    3221            2 :           if (where)
    3222            0 :             gfc_error ("%qs of %qs is PRIVATE at %L",
    3223              :                        gfc_op2string (op), derived->name, where);
    3224            2 :           if (t)
    3225            2 :             *t = false;
    3226              :         }
    3227              : 
    3228          892 :       return res;
    3229              :     }
    3230              : 
    3231              :   /* Otherwise, recurse on parent type if derived is an extension.  */
    3232        21085 :   if (derived->attr.extension)
    3233              :     {
    3234          839 :       gfc_symbol* super_type;
    3235          839 :       super_type = gfc_get_derived_super_type (derived);
    3236          839 :       gcc_assert (super_type);
    3237              : 
    3238          839 :       return gfc_find_typebound_intrinsic_op (super_type, t, op,
    3239          839 :                                               noaccess, where);
    3240              :     }
    3241              : 
    3242              :   /* Nothing found.  */
    3243              :   return NULL;
    3244              : }
    3245              : 
    3246              : 
    3247              : /* Get a typebound-procedure symtree or create and insert it if not yet
    3248              :    present.  This is like a very simplified version of gfc_get_sym_tree for
    3249              :    tbp-symtrees rather than regular ones.  */
    3250              : 
    3251              : gfc_symtree*
    3252         8944 : gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
    3253              : {
    3254         8944 :   gfc_symtree *result = gfc_find_symtree (*root, name);
    3255         8944 :   return result ? result : gfc_new_symtree (root, name);
    3256              : }
        

Generated by: LCOV version 2.4-beta

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