LCOV - code coverage report
Current view: top level - gcc/fortran - class.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.8 % 1811 1771
Test Date: 2026-06-20 15:32:29 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        11738 : insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
      76              : {
      77        11738 :   gfc_ref *new_ref;
      78        11738 :   int wcnt, ecnt;
      79              : 
      80        11738 :   gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
      81              : 
      82        11738 :   gfc_find_component (ts->u.derived, name, true, true, &new_ref);
      83              : 
      84        11738 :   gfc_get_errors (&wcnt, &ecnt);
      85        11738 :   if (ecnt > 0 && !new_ref)
      86            1 :     return;
      87        11737 :   gcc_assert (new_ref->u.c.component);
      88              : 
      89        11737 :   while (new_ref->next)
      90            0 :     new_ref = new_ref->next;
      91        11737 :   new_ref->next = *ref;
      92              : 
      93        11737 :   if (new_ref->next)
      94              :     {
      95        11737 :       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        11737 :       gcc_assert (strcmp (name, "_data") == 0);
     101              : 
     102        11737 :       if (new_ref->next->type == REF_COMPONENT)
     103              :         next = new_ref->next;
     104        11196 :       else if (new_ref->next->type == REF_ARRAY
     105        11196 :                && new_ref->next->next
     106         2258 :                && new_ref->next->next->type == REF_COMPONENT)
     107              :         next = new_ref->next->next;
     108              : 
     109         2730 :       if (next != NULL)
     110              :         {
     111         2730 :           gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
     112              :                       || new_ref->u.c.component->ts.type == BT_DERIVED);
     113         2730 :           next->u.c.sym = new_ref->u.c.component->ts.u.derived;
     114              :         }
     115              :     }
     116              : 
     117        11737 :   *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      1380918 : 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      1380918 :   if (ts->type != BT_CLASS)
     131              :     return false;
     132              : 
     133              :   /* Accessing a class container with an array reference is certainly wrong.  */
     134       113308 :   if (ref->type != REF_COMPONENT)
     135              :     return true;
     136              : 
     137              :   /* Accessing the class container's fields is fine.  */
     138       102111 :   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        15453 :   if (first_ref_in_chain && ts->u.derived->attr.extension)
     154        14912 :     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      4610212 : gfc_fix_class_refs (gfc_expr *e)
     169              : {
     170      4610212 :   gfc_typespec *ts;
     171      4610212 :   gfc_ref **ref;
     172              : 
     173      4610212 :   if ((e->expr_type != EXPR_VARIABLE
     174      2007580 :        && e->expr_type != EXPR_FUNCTION)
     175      2907815 :       || (e->expr_type == EXPR_FUNCTION
     176       305183 :           && e->value.function.isym != NULL))
     177              :     return;
     178              : 
     179      2652595 :   if (e->expr_type == EXPR_VARIABLE)
     180      2602632 :     ts = &e->symtree->n.sym->ts;
     181              :   else
     182              :     {
     183        49963 :       gfc_symbol *func;
     184              : 
     185        49963 :       gcc_assert (e->expr_type == EXPR_FUNCTION);
     186        49963 :       if (e->value.function.esym != NULL)
     187              :         func = e->value.function.esym;
     188              :       else
     189         1617 :         func = e->symtree->n.sym;
     190              : 
     191        49963 :       if (func->result != NULL)
     192        48658 :         ts = &func->result->ts;
     193              :       else
     194         1305 :         ts = &func->ts;
     195              :     }
     196              : 
     197      4033513 :   for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
     198              :     {
     199      1380918 :       if (class_data_ref_missing (ts, *ref, ref == &e->ref))
     200        11738 :         insert_component_ref (ts, ref, "_data");
     201              : 
     202      1380918 :       if ((*ref)->type == REF_COMPONENT)
     203       290610 :         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        60481 : gfc_add_component_ref (gfc_expr *e, const char *name)
     213              : {
     214        60481 :   gfc_component *c;
     215        60481 :   gfc_ref **tail = &(e->ref);
     216        60481 :   gfc_ref *ref, *next = NULL;
     217        60481 :   gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
     218        86264 :   while (*tail != NULL)
     219              :     {
     220        41077 :       if ((*tail)->type == REF_COMPONENT)
     221              :         {
     222        24808 :           if (strcmp ((*tail)->u.c.component->name, "_data") == 0
     223         1471 :                 && (*tail)->next
     224         1471 :                 && (*tail)->next->type == REF_ARRAY
     225         1387 :                 && (*tail)->next->next == NULL)
     226              :             return;
     227        23691 :           derived = (*tail)->u.c.component->ts.u.derived;
     228              :         }
     229        39960 :       if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
     230              :         break;
     231        25783 :       tail = &((*tail)->next);
     232              :     }
     233        59364 :   if (derived && derived->components && derived->components->next &&
     234        59357 :       derived->components->next->ts.type == BT_DERIVED &&
     235        45927 :       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        59364 :   if (*tail != NULL && strcmp (name, "_data") == 0)
     243              :     next = *tail;
     244              :   else
     245              :     /* Avoid losing memory.  */
     246        51213 :     gfc_free_ref_list (*tail);
     247        59364 :   c = gfc_find_component (derived, name, true, true, tail);
     248              : 
     249        59364 :   if (c) {
     250        59356 :     for (ref = *tail; ref->next; ref = ref->next)
     251              :       ;
     252        59356 :     ref->next = next;
     253        59356 :     if (!next)
     254        51205 :       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         5105 : gfc_add_class_array_ref (gfc_expr *e)
     265              : {
     266         5105 :   int rank = CLASS_DATA (e)->as->rank;
     267         5105 :   int corank = CLASS_DATA (e)->as->corank;
     268         5105 :   gfc_array_spec *as = CLASS_DATA (e)->as;
     269         5105 :   gfc_ref *ref = NULL;
     270         5105 :   gfc_add_data_component (e);
     271         5105 :   e->rank = rank;
     272         5105 :   e->corank = corank;
     273         9750 :   for (ref = e->ref; ref; ref = ref->next)
     274         9749 :     if (!ref->next)
     275              :       break;
     276         5105 :   if (ref && ref->type != REF_ARRAY)
     277              :     {
     278         1181 :       ref->next = gfc_get_ref ();
     279         1181 :       ref = ref->next;
     280         1181 :       ref->type = REF_ARRAY;
     281         1181 :       ref->u.ar.type = AR_FULL;
     282         1181 :       ref->u.ar.as = as;
     283              :     }
     284         5105 : }
     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         7302 : class_array_ref_detected (gfc_ref *ref, bool *full_array)
     294              : {
     295         7302 :   bool no_data = false;
     296         7302 :   bool with_data = false;
     297              : 
     298              :   /* An array reference with no _data component.  */
     299         7302 :   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         7716 :   if (ref && ref->type == REF_COMPONENT
     310         6826 :         && strcmp (ref->u.c.component->name, "_data") == 0)
     311              :     {
     312         6820 :       if (!ref->next)
     313              :         {
     314            0 :           with_data = true;
     315            0 :           if (full_array)
     316            0 :             *full_array = true;
     317              :         }
     318         6820 :       else if (ref->next && ref->next->type == REF_ARRAY
     319              :             && ref->type == REF_COMPONENT
     320         6820 :             && ref->next->u.ar.type != AR_ELEMENT)
     321              :         {
     322         6405 :           with_data = true;
     323         6405 :           if (full_array)
     324         2877 :             *full_array = ref->next->u.ar.type == AR_FULL;
     325              :         }
     326              :     }
     327              : 
     328         7302 :   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       275660 : gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
     337              : {
     338       275660 :   gfc_ref *ref;
     339              : 
     340       275660 :   if (!e->rank)
     341              :     return false;
     342              : 
     343       238283 :   if (full_array)
     344         3352 :     *full_array= false;
     345              : 
     346              :   /* Is this a class array object? ie. Is the symbol of type class?  */
     347       238283 :   if (e->symtree
     348       194886 :         && e->symtree->n.sym->ts.type == BT_CLASS
     349         7127 :         && CLASS_DATA (e->symtree->n.sym)
     350         7127 :         && CLASS_DATA (e->symtree->n.sym)->attr.dimension
     351       244405 :         && class_array_ref_detected (e->ref, full_array))
     352              :     return true;
     353              : 
     354              :   /* Or is this a class array component reference?  */
     355       432034 :   for (ref = e->ref; ref; ref = ref->next)
     356              :     {
     357       200601 :       if (ref->type == REF_COMPONENT
     358        20793 :             && ref->u.c.component->ts.type == BT_CLASS
     359         1326 :             && CLASS_DATA (ref->u.c.component)->attr.dimension
     360       201781 :             && 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        47856 : gfc_is_class_scalar_expr (gfc_expr *e)
     375              : {
     376        47856 :   gfc_ref *ref;
     377              : 
     378        47856 :   if (e->rank)
     379              :     return false;
     380              : 
     381              :   /* Is this a class object?  */
     382        42521 :   if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS
     383         2093 :       && CLASS_DATA (e->symtree->n.sym)
     384         2093 :       && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
     385         1793 :       && (e->ref == NULL
     386         1362 :           || (e->ref->type == REF_COMPONENT
     387         1360 :               && strcmp (e->ref->u.c.component->name, "_data") == 0
     388         1055 :               && (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        44593 :   for (ref = e->ref; ref; ref = ref->next)
     397              :     {
     398         4013 :       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         1616 : gfc_is_class_container_ref (gfc_expr *e)
     423              : {
     424         1616 :   gfc_ref *ref;
     425         1616 :   bool result;
     426              : 
     427         1616 :   if (e->expr_type != EXPR_VARIABLE)
     428          266 :     return e->ts.type == BT_CLASS;
     429              : 
     430         1350 :   if (e->symtree->n.sym->ts.type == BT_CLASS)
     431              :     result = true;
     432              :   else
     433         1128 :     result = false;
     434              : 
     435         2889 :   for (ref = e->ref; ref; ref = ref->next)
     436              :     {
     437         1539 :       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         1539 :         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         3445 : gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
     455              : {
     456         3445 :   gfc_expr *init;
     457         3445 :   gfc_component *comp;
     458         3445 :   gfc_symbol *vtab = NULL;
     459              : 
     460         3445 :   if (init_expr && init_expr->expr_type != EXPR_NULL)
     461         1690 :     vtab = gfc_find_vtab (&init_expr->ts);
     462              :   else
     463         1755 :     vtab = gfc_find_vtab (ts);
     464              : 
     465         6890 :   init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
     466         3445 :                                              &ts->u.derived->declared_at);
     467         3445 :   init->ts = *ts;
     468              : 
     469        10857 :   for (comp = ts->u.derived->components; comp; comp = comp->next)
     470              :     {
     471         7412 :       gfc_constructor *ctor = gfc_constructor_get();
     472         7412 :       if (strcmp (comp->name, "_vptr") == 0 && vtab)
     473         3445 :         ctor->expr = gfc_lval_expr_from_sym (vtab);
     474         3967 :       else if (init_expr && init_expr->expr_type != EXPR_NULL)
     475         1928 :           ctor->expr = gfc_copy_expr (init_expr);
     476              :       else
     477         2039 :         ctor->expr = gfc_get_null_expr (NULL);
     478         7412 :       gfc_constructor_append (&init->value.constructor, ctor);
     479              :     }
     480              : 
     481         3445 :   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       109776 : get_unique_type_string (gfc_symbol *derived)
     491              : {
     492       109776 :   const char *dt_name;
     493       109776 :   char *string;
     494       109776 :   size_t len;
     495       109776 :   if (derived->attr.unlimited_polymorphic)
     496              :     dt_name = "STAR";
     497              :   else
     498       102747 :     dt_name = gfc_dt_upper_string (derived->name);
     499       109776 :   len = strlen (dt_name) + 2;
     500       109776 :   if (derived->attr.unlimited_polymorphic)
     501              :     {
     502         7029 :       string = XNEWVEC (char, len);
     503         7029 :       sprintf (string, "_%s", dt_name);
     504              :     }
     505       102747 :   else if (derived->module)
     506              :     {
     507        41401 :       string = XNEWVEC (char, strlen (derived->module) + len);
     508        41401 :       sprintf (string, "%s_%s", derived->module, dt_name);
     509              :     }
     510        61346 :   else if (derived->ns->proc_name)
     511              :     {
     512        60552 :       string = XNEWVEC (char, strlen (derived->ns->proc_name->name) + len);
     513        60552 :       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       109776 :   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        94473 : get_unique_hashed_string (char *string, gfc_symbol *derived)
     529              : {
     530              :   /* Provide sufficient space to hold "symbol.symbol_symbol".  */
     531        94473 :   char *tmp;
     532        94473 :   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        94473 :   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        94332 :     strcpy (string, tmp);
     544        94473 :   free (tmp);
     545        94473 : }
     546              : 
     547              : 
     548              : /* Assign a hash value for a derived type. The algorithm is that of SDBM.  */
     549              : 
     550              : unsigned int
     551        15303 : gfc_hash_value (gfc_symbol *sym)
     552              : {
     553        15303 :   unsigned int hash = 0;
     554              :   /* Provide sufficient space to hold "symbol.symbol_symbol".  */
     555        15303 :   char *c;
     556        15303 :   int i, len;
     557              : 
     558        15303 :   c = get_unique_type_string (sym);
     559        15303 :   len = strlen (c);
     560              : 
     561       244409 :   for (i = 0; i < len; i++)
     562       229106 :     hash = (hash << 6) + (hash << 16) - hash + c[i];
     563              : 
     564        15303 :   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        15303 :   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          931 : gfc_intrinsic_hash_value (gfc_typespec *ts)
     575              : {
     576          931 :   unsigned int hash = 0;
     577          931 :   const char *c = gfc_typename (ts, true);
     578          931 :   int i, len;
     579              : 
     580          931 :   len = strlen (c);
     581              : 
     582        10129 :   for (i = 0; i < len; i++)
     583         9198 :     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          931 :   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 traverses 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        13277 : gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
     645              :                         gfc_array_spec **as)
     646              : {
     647        13277 :   char tname[GFC_MAX_SYMBOL_LEN+1];
     648        13277 :   char *name;
     649        13277 :   gfc_typespec *orig_ts = ts;
     650        13277 :   gfc_symbol *fclass;
     651        13277 :   gfc_symbol *vtab;
     652        13277 :   gfc_component *c;
     653        13277 :   gfc_namespace *ns;
     654        13277 :   int rank;
     655              : 
     656        13277 :   gcc_assert (as);
     657              : 
     658              :   /* We cannot build the class container now.  */
     659        13277 :   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        13276 :   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        13275 :   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         6311 :   attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
     679        13540 :                    || attr->select_type_temporary || attr->associate_var;
     680              : 
     681        13275 :   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        13200 :   rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
     687              : 
     688        13200 :   if (!ts->u.derived)
     689              :     return false;
     690              : 
     691        13195 :   get_unique_hashed_string (tname, ts->u.derived);
     692        13195 :   if ((*as) && attr->allocatable)
     693         2054 :     name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
     694        11141 :   else if ((*as) && attr->pointer)
     695         1193 :     name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
     696         9948 :   else if ((*as))
     697         1254 :     name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
     698         8694 :   else if (attr->pointer)
     699         1807 :     name = xasprintf ("__class_%s_p", tname);
     700         6887 :   else if (attr->allocatable)
     701         2166 :     name = xasprintf ("__class_%s_a", tname);
     702              :   else
     703         4721 :     name = xasprintf ("__class_%s_t", tname);
     704              : 
     705        13195 :   if (ts->u.derived->attr.unlimited_polymorphic)
     706              :     {
     707              :       /* Find the top-level namespace.  */
     708         4730 :       for (ns = gfc_current_ns; ns; ns = ns->parent)
     709         4730 :         if (!ns->parent)
     710              :           break;
     711              :     }
     712              :   else
     713        10647 :     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        13195 :   if (attr->dummy && (*as)
     721         1918 :       && ((!attr->codimension
     722         1748 :            && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK))
     723         1683 :           || (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        12859 :     gfc_find_symbol (name, ns, 0, &fclass);
     742              : 
     743        13195 :   if (fclass == NULL)
     744              :     {
     745         8001 :       gfc_symtree *st;
     746              :       /* If not there, create a new symbol.  */
     747         8001 :       fclass = gfc_new_symbol (name, ns);
     748         8001 :       st = gfc_new_symtree (&ns->sym_root, name);
     749         8001 :       st->n.sym = fclass;
     750         8001 :       gfc_set_sym_referenced (fclass);
     751         8001 :       fclass->refs++;
     752         8001 :       fclass->ts.type = BT_UNKNOWN;
     753         8001 :       if (!ts->u.derived->attr.unlimited_polymorphic)
     754         6435 :         fclass->attr.abstract = ts->u.derived->attr.abstract;
     755         8001 :       fclass->f2k_derived = gfc_get_namespace (NULL, 0);
     756         8001 :       if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
     757              :                            &gfc_current_locus))
     758              :         return false;
     759              : 
     760              :       /* Add component '_data'.  */
     761         8001 :       if (!gfc_add_component (fclass, "_data", &c))
     762              :         return false;
     763         8001 :       c->ts = *ts;
     764         8001 :       c->ts.type = BT_DERIVED;
     765         8001 :       c->attr.access = ACCESS_PRIVATE;
     766         8001 :       c->ts.u.derived = ts->u.derived;
     767         8001 :       c->attr.class_pointer = attr->pointer;
     768         6298 :       c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
     769        10778 :                         || attr->select_type_temporary;
     770         8001 :       c->attr.allocatable = attr->allocatable;
     771         8001 :       c->attr.dimension = attr->dimension;
     772         8001 :       c->attr.codimension = attr->codimension;
     773         8001 :       c->attr.abstract = fclass->attr.abstract;
     774         8001 :       c->as = (*as);
     775         8001 :       c->initializer = NULL;
     776              : 
     777              :       /* Add component '_vptr'.  */
     778         8001 :       if (!gfc_add_component (fclass, "_vptr", &c))
     779              :         return false;
     780         8001 :       c->ts.type = BT_DERIVED;
     781         8001 :       c->attr.access = ACCESS_PRIVATE;
     782         8001 :       c->attr.pointer = 1;
     783              : 
     784         8001 :       if (ts->u.derived->attr.unlimited_polymorphic)
     785              :         {
     786         1566 :           vtab = gfc_find_derived_vtab (ts->u.derived);
     787         1566 :           gcc_assert (vtab);
     788         1566 :           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         1566 :           if (!gfc_add_component (fclass, "_len", &c))
     794              :             return false;
     795         1566 :           c->ts.type = BT_INTEGER;
     796         1566 :           c->ts.kind = gfc_charlen_int_kind;
     797         1566 :           c->attr.access = ACCESS_PRIVATE;
     798         1566 :           c->attr.artificial = 1;
     799              :         }
     800              :       else
     801              :         /* Build vtab later.  */
     802         6435 :         c->ts.u.derived = NULL;
     803              :     }
     804              : 
     805        13195 :   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        10647 :       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        10647 :       fclass->attr.extension = ts->u.derived->attr.extension + 1;
     817        10647 :       fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
     818        10647 :       fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
     819              :     }
     820              : 
     821        13195 :   fclass->attr.is_class = 1;
     822        13195 :   orig_ts->u.derived = fclass;
     823        13195 :   attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
     824        13195 :   (*as) = NULL;
     825        13195 :   free (name);
     826        13195 :   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         4863 : add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
     885              : {
     886         4863 :   gfc_component *c;
     887         4863 :   bool is_abstract = false;
     888              : 
     889         4863 :   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         4863 :   if (c && c->tb && c->tb->u.specific
     894         1338 :       && c->tb->u.specific->n.sym->attr.abstract)
     895         4863 :     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         4863 :   if (tb->non_overridable && !tb->overridden && !is_abstract && c)
     902            7 :     return;
     903              : 
     904         4856 :   if (c == NULL)
     905              :     {
     906              :       /* Add procedure component.  */
     907         3507 :       if (!gfc_add_component (vtype, name, &c))
     908              :         return;
     909              : 
     910         3507 :       if (!c->tb)
     911         3507 :         c->tb = XCNEW (gfc_typebound_proc);
     912         3507 :       *c->tb = *tb;
     913         3507 :       c->tb->ppc = 1;
     914         3507 :       c->attr.procedure = 1;
     915         3507 :       c->attr.proc_pointer = 1;
     916         3507 :       c->attr.flavor = FL_PROCEDURE;
     917         3507 :       c->attr.access = ACCESS_PRIVATE;
     918         3507 :       c->attr.external = 1;
     919         3507 :       c->attr.untyped = 1;
     920         3507 :       c->attr.if_source = IFSRC_IFBODY;
     921              :     }
     922         1349 :   else if (c->attr.proc_pointer && c->tb)
     923              :     {
     924         1349 :       *c->tb = *tb;
     925         1349 :       c->tb->ppc = 1;
     926              :     }
     927              : 
     928         4856 :   if (tb->u.specific)
     929              :     {
     930         4838 :       gfc_symbol *ifc = tb->u.specific->n.sym;
     931         4838 :       c->ts.interface = ifc;
     932         4838 :       if (!tb->deferred)
     933         4107 :         c->initializer = gfc_get_variable_expr (tb->u.specific);
     934         4838 :       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         4774 : add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
     943              : {
     944         4774 :   if (!st)
     945              :     return;
     946              : 
     947         4774 :   if (st->left)
     948         1201 :     add_procs_to_declared_vtab1 (st->left, vtype);
     949              : 
     950         4774 :   if (st->right)
     951         1174 :     add_procs_to_declared_vtab1 (st->right, vtype);
     952              : 
     953         4774 :   if (st->n.tb && !st->n.tb->error
     954         4712 :       && !st->n.tb->is_generic && st->n.tb->u.specific)
     955         4041 :     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         1473 : copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
     963              : {
     964         1473 :   gfc_component *cmp;
     965         1473 :   gfc_symbol *vtab;
     966              : 
     967         1473 :   vtab = gfc_find_derived_vtab (declared);
     968              : 
     969        12642 :   for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
     970              :     {
     971        11169 :       if (gfc_find_component (vtype, cmp->name, true, true, NULL))
     972        10347 :         continue;
     973              : 
     974          822 :       add_proc_comp (vtype, cmp->name, cmp->tb);
     975              :     }
     976         1473 : }
     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        10169 : has_finalizer_component (gfc_symbol *derived)
     985              : {
     986        10169 :    gfc_component *c;
     987              : 
     988        21865 :   for (c = derived->components; c; c = c->next)
     989        11732 :     if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable
     990         1946 :         && c->attr.flavor != FL_PROCEDURE)
     991              :       {
     992         1940 :         if (c->ts.u.derived->f2k_derived
     993         1837 :             && 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         1904 :         if (!gfc_compare_derived_types (derived, c->ts.u.derived)
    1000         1904 :             && has_finalizer_component (c->ts.u.derived))
    1001              :           return true;
    1002              :       }
    1003              :   return false;
    1004              : }
    1005              : 
    1006              : 
    1007              : static bool
    1008         7652 : comp_is_finalizable (gfc_component *comp)
    1009              : {
    1010         7652 :   if (comp->attr.proc_pointer)
    1011              :     return false;
    1012         7574 :   else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
    1013              :     return true;
    1014         1142 :   else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
    1015         4746 :            && (comp->ts.u.derived->attr.alloc_comp
    1016          492 :                || has_finalizer_component (comp->ts.u.derived)
    1017          492 :                || (comp->ts.u.derived->f2k_derived
    1018          468 :                    && comp->ts.u.derived->f2k_derived->finalizers)))
    1019          727 :     return true;
    1020         2927 :   else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1021          648 :             && 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         3888 : 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         3888 :   gfc_expr *e;
    1043         3888 :   gfc_ref *ref;
    1044         3888 :   gfc_was_finalized *f;
    1045              : 
    1046         3888 :   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         3902 :   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         2833 :   e = gfc_copy_expr (expr);
    1058         2833 :   if (!e->ref)
    1059         2434 :     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         2833 :   ref->type = REF_COMPONENT;
    1068         2833 :   ref->u.c.sym = derived;
    1069         2833 :   ref->u.c.component = comp;
    1070         2833 :   e->ts = comp->ts;
    1071              : 
    1072         2833 :   if (comp->attr.dimension || comp->attr.codimension
    1073         1211 :       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1074          337 :           && (CLASS_DATA (comp)->attr.dimension
    1075          223 :               || CLASS_DATA (comp)->attr.codimension)))
    1076              :     {
    1077         1744 :       ref->next = gfc_get_ref ();
    1078         1744 :       ref->next->type = REF_ARRAY;
    1079         1744 :       ref->next->u.ar.dimen = 0;
    1080         1744 :       ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
    1081              :                                                         : comp->as;
    1082         1744 :       e->rank = ref->next->u.ar.as->rank;
    1083         1744 :       e->corank = ref->next->u.ar.as->corank;
    1084         1763 :       ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
    1085              :     }
    1086              : 
    1087              :   /* Call DEALLOCATE (comp, stat=ignore).  */
    1088         2833 :   if (comp->attr.allocatable
    1089          727 :       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1090          337 :           && CLASS_DATA (comp)->attr.allocatable))
    1091              :     {
    1092         2443 :       gfc_code *dealloc, *block = NULL;
    1093              : 
    1094              :       /* Add IF (fini_coarray).  */
    1095         2443 :       if (comp->attr.codimension
    1096         2426 :           || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
    1097          337 :               && 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         2443 :       dealloc = gfc_get_code (EXEC_DEALLOCATE);
    1114              : 
    1115         2443 :       dealloc->ext.alloc.list = gfc_get_alloc ();
    1116         2443 :       dealloc->ext.alloc.list->expr = e;
    1117         2443 :       dealloc->expr1 = gfc_lval_expr_from_sym (stat);
    1118              : 
    1119         2443 :       gfc_code *cond = gfc_get_code (EXEC_IF);
    1120         2443 :       cond->block = gfc_get_code (EXEC_IF);
    1121         2443 :       cond->block->expr1 = gfc_get_expr ();
    1122         2443 :       cond->block->expr1->expr_type = EXPR_FUNCTION;
    1123         2443 :       cond->block->expr1->where = gfc_current_locus;
    1124         2443 :       gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
    1125         2443 :       cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
    1126         2443 :       cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
    1127         2443 :       cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
    1128         2443 :       gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
    1129         2443 :       cond->block->expr1->ts.type = BT_LOGICAL;
    1130         2443 :       cond->block->expr1->ts.kind = gfc_default_logical_kind;
    1131         2443 :       cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
    1132         2443 :       cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
    1133         2443 :       cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
    1134         2443 :       cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
    1135         2443 :       cond->block->next = dealloc;
    1136              : 
    1137         2443 :       if (block)
    1138           31 :         block->next = cond;
    1139         2412 :       else if (*code)
    1140              :         {
    1141         2412 :           (*code)->next = cond;
    1142         2412 :           (*code) = (*code)->next;
    1143              :         }
    1144              :       else
    1145            0 :         (*code) = cond;
    1146              : 
    1147              :     }
    1148          390 :   else if (comp->ts.type == BT_DERIVED
    1149          390 :             && comp->ts.u.derived->f2k_derived
    1150          390 :             && comp->ts.u.derived->f2k_derived->finalizers)
    1151              :     {
    1152              :       /* Call FINAL_WRAPPER (comp);  */
    1153           89 :       gfc_code *final_wrap;
    1154           89 :       gfc_symbol *vtab, *byte_stride;
    1155           89 :       gfc_expr *scalar, *size_expr, *fini_coarray_expr;
    1156           89 :       gfc_component *c;
    1157              : 
    1158           89 :       vtab = gfc_find_derived_vtab (comp->ts.u.derived);
    1159          534 :       for (c = vtab->ts.u.derived->components; c; c = c->next)
    1160          534 :         if (strcmp (c->name, "_final") == 0)
    1161              :           break;
    1162              : 
    1163           89 :       gcc_assert (c);
    1164              : 
    1165              :       /* Set scalar argument for storage_size. A leading underscore in
    1166              :          the name prevents an unwanted finalization.  */
    1167           89 :       gfc_get_symbol ("_comp_byte_stride", sub_ns, &byte_stride);
    1168           89 :       byte_stride->ts = e->ts;
    1169           89 :       byte_stride->attr.flavor = FL_VARIABLE;
    1170           89 :       byte_stride->attr.value = 1;
    1171           89 :       byte_stride->attr.artificial = 1;
    1172           89 :       gfc_set_sym_referenced (byte_stride);
    1173           89 :       gfc_commit_symbol (byte_stride);
    1174           89 :       scalar = gfc_lval_expr_from_sym (byte_stride);
    1175              : 
    1176           89 :       final_wrap = gfc_get_code (EXEC_CALL);
    1177           89 :       final_wrap->symtree = c->initializer->symtree;
    1178           89 :       final_wrap->resolved_sym = c->initializer->symtree->n.sym;
    1179           89 :       final_wrap->ext.actual = gfc_get_actual_arglist ();
    1180           89 :       final_wrap->ext.actual->expr = e;
    1181              : 
    1182              :       /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE.  */
    1183           89 :       size_expr = gfc_get_expr ();
    1184           89 :       size_expr->where = gfc_current_locus;
    1185           89 :       size_expr->expr_type = EXPR_OP;
    1186           89 :       size_expr->value.op.op = INTRINSIC_DIVIDE;
    1187              : 
    1188              :       /* STORAGE_SIZE (array,kind=c_intptr_t).  */
    1189           89 :       size_expr->value.op.op1
    1190           89 :         = 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           89 :       size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
    1198              :                                                   gfc_character_storage_size);
    1199           89 :       size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
    1200           89 :       size_expr->ts = size_expr->value.op.op1->ts;
    1201              : 
    1202              :       /* Which provides the argument 'byte_stride'.....  */
    1203           89 :       final_wrap->ext.actual->next = gfc_get_actual_arglist ();
    1204           89 :       final_wrap->ext.actual->next->expr = size_expr;
    1205              : 
    1206              :       /* ...and last of all the 'fini_coarray' argument.  */
    1207           89 :       fini_coarray_expr = gfc_lval_expr_from_sym (fini_coarray);
    1208           89 :       final_wrap->ext.actual->next->next = gfc_get_actual_arglist ();
    1209           89 :       final_wrap->ext.actual->next->next->expr = fini_coarray_expr;
    1210              : 
    1211           89 :       if (*code)
    1212              :         {
    1213           89 :           (*code)->next = final_wrap;
    1214           89 :           (*code) = (*code)->next;
    1215              :         }
    1216              :       else
    1217            0 :         (*code) = final_wrap;
    1218           89 :     }
    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         2833 :   f = sub_ns->was_finalized;
    1234         2833 :   sub_ns->was_finalized = XCNEW (gfc_was_finalized);
    1235         2833 :   sub_ns->was_finalized->e = expr;
    1236         2833 :   sub_ns->was_finalized->c = comp;
    1237         2833 :   sub_ns->was_finalized->next = f;
    1238         2833 :   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         2560 : finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
    1248              :                          gfc_expr *offset, gfc_namespace *sub_ns)
    1249              : {
    1250         2560 :   gfc_code *block;
    1251         2560 :   gfc_expr *expr, *expr2;
    1252              : 
    1253              :   /* C_F_POINTER().  */
    1254         2560 :   block = gfc_get_code (EXEC_CALL);
    1255         2560 :   gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
    1256         2560 :   block->resolved_sym = block->symtree->n.sym;
    1257         2560 :   block->resolved_sym->attr.flavor = FL_PROCEDURE;
    1258         2560 :   block->resolved_sym->attr.intrinsic = 1;
    1259         2560 :   block->resolved_sym->attr.subroutine = 1;
    1260         2560 :   block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
    1261         2560 :   block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
    1262         2560 :   block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
    1263         2560 :   gfc_commit_symbol (block->resolved_sym);
    1264              : 
    1265              :   /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t).  */
    1266         2560 :   block->ext.actual = gfc_get_actual_arglist ();
    1267         2560 :   block->ext.actual->next = gfc_get_actual_arglist ();
    1268         2560 :   block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
    1269              :                                                     NULL, 0);
    1270         2560 :   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         2560 :   expr = gfc_get_expr ();
    1276         2560 :   expr->expr_type = EXPR_FUNCTION;
    1277         2560 :   gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
    1278         2560 :   expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
    1279         2560 :   expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
    1280         2560 :   expr->symtree->n.sym->attr.intrinsic = 1;
    1281         2560 :   expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
    1282         2560 :   expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
    1283         2560 :   expr->value.function.actual = gfc_get_actual_arglist ();
    1284         2560 :   expr->value.function.actual->expr
    1285         2560 :             = gfc_lval_expr_from_sym (array);
    1286         2560 :   expr->symtree->n.sym->result = expr->symtree->n.sym;
    1287         2560 :   gfc_commit_symbol (expr->symtree->n.sym);
    1288         2560 :   expr->ts.type = BT_INTEGER;
    1289         2560 :   expr->ts.kind = gfc_index_integer_kind;
    1290         2560 :   expr->where = gfc_current_locus;
    1291              : 
    1292              :   /* TRANSFER.  */
    1293         2560 :   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         2560 :   expr2->ts.type = BT_INTEGER;
    1298         2560 :   expr2->ts.kind = gfc_index_integer_kind;
    1299              : 
    1300              :   /* <array addr> + <offset>.  */
    1301         2560 :   block->ext.actual->expr = gfc_get_expr ();
    1302         2560 :   block->ext.actual->expr->expr_type = EXPR_OP;
    1303         2560 :   block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
    1304         2560 :   block->ext.actual->expr->value.op.op1 = expr2;
    1305         2560 :   block->ext.actual->expr->value.op.op2 = offset;
    1306         2560 :   block->ext.actual->expr->ts = expr->ts;
    1307         2560 :   block->ext.actual->expr->where = gfc_current_locus;
    1308              : 
    1309              :   /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=.  */
    1310         2560 :   block->ext.actual->next = gfc_get_actual_arglist ();
    1311         2560 :   block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
    1312         2560 :   block->ext.actual->next->next = gfc_get_actual_arglist ();
    1313              : 
    1314         2560 :   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         2338 : 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         2338 :   gfc_iterator *iter;
    1333         2338 :   gfc_expr *expr, *expr2;
    1334              : 
    1335              :   /* offset = 0.  */
    1336         2338 :   block->next = gfc_get_code (EXEC_ASSIGN);
    1337         2338 :   block = block->next;
    1338         2338 :   block->expr1 = gfc_lval_expr_from_sym (offset);
    1339         2338 :   block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1340              : 
    1341              :   /* Create loop.  */
    1342         2338 :   iter = gfc_get_iterator ();
    1343         2338 :   iter->var = gfc_lval_expr_from_sym (idx2);
    1344         2338 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1345         2338 :   iter->end = gfc_copy_expr (rank);
    1346         2338 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1347         2338 :   block->next = gfc_get_code (EXEC_DO);
    1348         2338 :   block = block->next;
    1349         2338 :   block->ext.iterator = iter;
    1350         2338 :   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         2338 :   expr = gfc_lval_expr_from_sym (sizes);
    1357         2338 :   expr->ref = gfc_get_ref ();
    1358         2338 :   expr->ref->type = REF_ARRAY;
    1359         2338 :   expr->ref->u.ar.as = sizes->as;
    1360         2338 :   expr->ref->u.ar.type = AR_ELEMENT;
    1361         2338 :   expr->ref->u.ar.dimen = 1;
    1362         2338 :   expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1363         2338 :   expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
    1364         2338 :   expr->where = sizes->declared_at;
    1365              : 
    1366         2338 :   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         2338 :   expr->ts = idx->ts;
    1370              : 
    1371              :   /* (...) / sizes(idx2-1).  */
    1372         2338 :   expr2 = gfc_get_expr ();
    1373         2338 :   expr2->expr_type = EXPR_OP;
    1374         2338 :   expr2->value.op.op = INTRINSIC_DIVIDE;
    1375         2338 :   expr2->value.op.op1 = expr;
    1376         2338 :   expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
    1377         2338 :   expr2->value.op.op2->ref = gfc_get_ref ();
    1378         2338 :   expr2->value.op.op2->ref->type = REF_ARRAY;
    1379         2338 :   expr2->value.op.op2->ref->u.ar.as = sizes->as;
    1380         2338 :   expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    1381         2338 :   expr2->value.op.op2->ref->u.ar.dimen = 1;
    1382         2338 :   expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1383         2338 :   expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
    1384         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
    1385         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
    1386         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    1387         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
    1388         2338 :         = gfc_lval_expr_from_sym (idx2);
    1389         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
    1390         2338 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1391         2338 :   expr2->value.op.op2->ref->u.ar.start[0]->ts
    1392         2338 :         = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
    1393         2338 :   expr2->ts = idx->ts;
    1394         2338 :   expr2->where = gfc_current_locus;
    1395              : 
    1396              :   /* ... * strides(idx2).  */
    1397         2338 :   expr = gfc_get_expr ();
    1398         2338 :   expr->expr_type = EXPR_OP;
    1399         2338 :   expr->value.op.op = INTRINSIC_TIMES;
    1400         2338 :   expr->value.op.op1 = expr2;
    1401         2338 :   expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
    1402         2338 :   expr->value.op.op2->ref = gfc_get_ref ();
    1403         2338 :   expr->value.op.op2->ref->type = REF_ARRAY;
    1404         2338 :   expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    1405         2338 :   expr->value.op.op2->ref->u.ar.dimen = 1;
    1406         2338 :   expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    1407         2338 :   expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
    1408         2338 :   expr->value.op.op2->ref->u.ar.as = strides->as;
    1409         2338 :   expr->ts = idx->ts;
    1410         2338 :   expr->where = gfc_current_locus;
    1411              : 
    1412              :   /* offset = offset + ...  */
    1413         2338 :   block->block->next = gfc_get_code (EXEC_ASSIGN);
    1414         2338 :   block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
    1415         2338 :   block->block->next->expr2 = gfc_get_expr ();
    1416         2338 :   block->block->next->expr2->expr_type = EXPR_OP;
    1417         2338 :   block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
    1418         2338 :   block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
    1419         2338 :   block->block->next->expr2->value.op.op2 = expr;
    1420         2338 :   block->block->next->expr2->ts = idx->ts;
    1421         2338 :   block->block->next->expr2->where = gfc_current_locus;
    1422              : 
    1423              :   /* After the loop:  offset = offset * byte_stride.  */
    1424         2338 :   block->next = gfc_get_code (EXEC_ASSIGN);
    1425         2338 :   block = block->next;
    1426         2338 :   block->expr1 = gfc_lval_expr_from_sym (offset);
    1427         2338 :   block->expr2 = gfc_get_expr ();
    1428         2338 :   block->expr2->expr_type = EXPR_OP;
    1429         2338 :   block->expr2->value.op.op = INTRINSIC_TIMES;
    1430         2338 :   block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
    1431         2338 :   block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
    1432         2338 :   block->expr2->ts = block->expr2->value.op.op1->ts;
    1433         2338 :   block->expr2->where = gfc_current_locus;
    1434         2338 :   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        10607 : generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
    1732              :                                const char *tname, gfc_component *vtab_final)
    1733              : {
    1734        10607 :   gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
    1735        10607 :   gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
    1736        10607 :   gfc_symbol *result = NULL;
    1737        10607 :   gfc_component *comp;
    1738        10607 :   gfc_namespace *sub_ns;
    1739        10607 :   gfc_code *last_code, *block;
    1740        10607 :   char *name;
    1741        10607 :   char *result_name;
    1742        10607 :   bool finalizable_comp = false;
    1743        10607 :   gfc_expr *ancestor_wrapper = NULL, *rank;
    1744        10607 :   gfc_iterator *iter;
    1745              : 
    1746        10607 :   if (derived->attr.unlimited_polymorphic || derived->error)
    1747              :     {
    1748          757 :       vtab_final->initializer = gfc_get_null_expr (NULL);
    1749         8253 :       return;
    1750              :     }
    1751              : 
    1752              :   /* Search for the ancestor's finalizers.  */
    1753         1352 :   if (derived->attr.extension && derived->components
    1754        11202 :       && (!derived->components->ts.u.derived->attr.abstract
    1755          305 :           || has_finalizer_component (derived)))
    1756              :     {
    1757         1047 :       gfc_symbol *vtab;
    1758         1047 :       gfc_component *comp;
    1759              : 
    1760         1047 :       vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
    1761         6282 :       for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
    1762         6282 :         if (comp->name[0] == '_' && comp->name[1] == 'f')
    1763              :           {
    1764         1047 :             ancestor_wrapper = comp->initializer;
    1765         1047 :             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         1047 :   if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
    1773         9670 :       && !derived->attr.alloc_comp
    1774         7790 :       && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
    1775         8515 :       && !has_finalizer_component (derived))
    1776              :     {
    1777         7432 :       vtab_final->initializer = gfc_get_null_expr (NULL);
    1778         7432 :       gcc_assert (vtab_final->ts.interface == NULL);
    1779              :       return;
    1780              :     }
    1781              :   else
    1782              :     /* Check whether there are new allocatable components.  */
    1783         6362 :     for (comp = derived->components; comp; comp = comp->next)
    1784              :       {
    1785         3944 :         if (comp == derived->components && derived->attr.extension
    1786          351 :             && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    1787          180 :         continue;
    1788              : 
    1789         3764 :         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         2418 :   if (!finalizable_comp
    1795          428 :       && (!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         2354 :   sub_ns = gfc_get_namespace (ns, 0);
    1817         2354 :   sub_ns->sibling = ns->contained;
    1818         2354 :   ns->contained = sub_ns;
    1819         2354 :   sub_ns->resolved = 1;
    1820              : 
    1821              :   /* Set up the procedure symbol.  */
    1822         2354 :   name = xasprintf ("__final_%s", tname);
    1823         2354 :   gfc_get_symbol (name, sub_ns, &final);
    1824         2354 :   sub_ns->proc_name = final;
    1825         2354 :   final->attr.flavor = FL_PROCEDURE;
    1826         2354 :   final->attr.function = 1;
    1827         2354 :   final->attr.pure = 0;
    1828         2354 :   final->attr.recursive = 1;
    1829         2354 :   final->ts.type = BT_INTEGER;
    1830         2354 :   final->ts.kind = 4;
    1831         2354 :   final->attr.artificial = 1;
    1832         2354 :   final->attr.always_explicit = 1;
    1833         2354 :   final->attr.if_source = IFSRC_DECL;
    1834         2354 :   if (ns->proc_name->attr.flavor == FL_MODULE)
    1835         1995 :     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         2354 :   result_name = xasprintf ("__result_%s", tname);
    1842         2354 :   if (gfc_get_symbol (result_name, sub_ns, &result) != 0)
    1843            0 :     gfc_internal_error ("Failed to create finalizer result symbol");
    1844         2354 :   free (result_name);
    1845              : 
    1846         2354 :   if (!gfc_add_flavor (&result->attr, FL_VARIABLE, result->name,
    1847              :                        &gfc_current_locus)
    1848         2354 :       || !gfc_add_result (&result->attr, result->name, &gfc_current_locus))
    1849            0 :     gfc_internal_error ("Failed to set finalizer result attributes");
    1850              : 
    1851         2354 :   result->ts = final->ts;
    1852         2354 :   result->attr.artificial = 1;
    1853         2354 :   gfc_set_sym_referenced (result);
    1854         2354 :   gfc_commit_symbol (result);
    1855         2354 :   final->result = result;
    1856         2354 :   gfc_set_sym_referenced (final);
    1857         2354 :   gfc_commit_symbol (final);
    1858              : 
    1859              :   /* Set up formal argument.  */
    1860         2354 :   gfc_get_symbol ("array", sub_ns, &array);
    1861         2354 :   array->ts.type = BT_DERIVED;
    1862         2354 :   array->ts.u.derived = derived;
    1863         2354 :   array->attr.flavor = FL_VARIABLE;
    1864         2354 :   array->attr.dummy = 1;
    1865         2354 :   array->attr.contiguous = 1;
    1866         2354 :   array->attr.dimension = 1;
    1867         2354 :   array->attr.artificial = 1;
    1868         2354 :   array->as = gfc_get_array_spec();
    1869         2354 :   array->as->type = AS_ASSUMED_RANK;
    1870         2354 :   array->as->rank = -1;
    1871         2354 :   array->attr.intent = INTENT_INOUT;
    1872         2354 :   gfc_set_sym_referenced (array);
    1873         2354 :   final->formal = gfc_get_formal_arglist ();
    1874         2354 :   final->formal->sym = array;
    1875         2354 :   gfc_commit_symbol (array);
    1876              : 
    1877              :   /* Set up formal argument.  */
    1878         2354 :   gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
    1879         2354 :   byte_stride->ts.type = BT_INTEGER;
    1880         2354 :   byte_stride->ts.kind = gfc_index_integer_kind;
    1881         2354 :   byte_stride->attr.flavor = FL_VARIABLE;
    1882         2354 :   byte_stride->attr.dummy = 1;
    1883         2354 :   byte_stride->attr.value = 1;
    1884         2354 :   byte_stride->attr.artificial = 1;
    1885         2354 :   gfc_set_sym_referenced (byte_stride);
    1886         2354 :   final->formal->next = gfc_get_formal_arglist ();
    1887         2354 :   final->formal->next->sym = byte_stride;
    1888         2354 :   gfc_commit_symbol (byte_stride);
    1889              : 
    1890              :   /* Set up formal argument.  */
    1891         2354 :   gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
    1892         2354 :   fini_coarray->ts.type = BT_LOGICAL;
    1893         2354 :   fini_coarray->ts.kind = 1;
    1894         2354 :   fini_coarray->attr.flavor = FL_VARIABLE;
    1895         2354 :   fini_coarray->attr.dummy = 1;
    1896         2354 :   fini_coarray->attr.value = 1;
    1897         2354 :   fini_coarray->attr.artificial = 1;
    1898         2354 :   gfc_set_sym_referenced (fini_coarray);
    1899         2354 :   final->formal->next->next = gfc_get_formal_arglist ();
    1900         2354 :   final->formal->next->next->sym = fini_coarray;
    1901         2354 :   gfc_commit_symbol (fini_coarray);
    1902              : 
    1903              :   /* Local variables.  */
    1904              : 
    1905         2354 :   gfc_get_symbol ("idx", sub_ns, &idx);
    1906         2354 :   idx->ts.type = BT_INTEGER;
    1907         2354 :   idx->ts.kind = gfc_index_integer_kind;
    1908         2354 :   idx->attr.flavor = FL_VARIABLE;
    1909         2354 :   idx->attr.artificial = 1;
    1910         2354 :   gfc_set_sym_referenced (idx);
    1911         2354 :   gfc_commit_symbol (idx);
    1912              : 
    1913         2354 :   gfc_get_symbol ("idx2", sub_ns, &idx2);
    1914         2354 :   idx2->ts.type = BT_INTEGER;
    1915         2354 :   idx2->ts.kind = gfc_index_integer_kind;
    1916         2354 :   idx2->attr.flavor = FL_VARIABLE;
    1917         2354 :   idx2->attr.artificial = 1;
    1918         2354 :   gfc_set_sym_referenced (idx2);
    1919         2354 :   gfc_commit_symbol (idx2);
    1920              : 
    1921         2354 :   gfc_get_symbol ("offset", sub_ns, &offset);
    1922         2354 :   offset->ts.type = BT_INTEGER;
    1923         2354 :   offset->ts.kind = gfc_index_integer_kind;
    1924         2354 :   offset->attr.flavor = FL_VARIABLE;
    1925         2354 :   offset->attr.artificial = 1;
    1926         2354 :   gfc_set_sym_referenced (offset);
    1927         2354 :   gfc_commit_symbol (offset);
    1928              : 
    1929              :   /* Create RANK expression.  */
    1930         2354 :   rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
    1931              :                                    gfc_current_locus, 1,
    1932              :                                    gfc_lval_expr_from_sym (array));
    1933         2354 :   if (rank->ts.kind != idx->ts.kind)
    1934         2354 :     gfc_convert_type_warn (rank, &idx->ts, 2, 0);
    1935              : 
    1936              :   /* Create is_contiguous variable.  */
    1937         2354 :   gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
    1938         2354 :   is_contiguous->ts.type = BT_LOGICAL;
    1939         2354 :   is_contiguous->ts.kind = gfc_default_logical_kind;
    1940         2354 :   is_contiguous->attr.flavor = FL_VARIABLE;
    1941         2354 :   is_contiguous->attr.artificial = 1;
    1942         2354 :   gfc_set_sym_referenced (is_contiguous);
    1943         2354 :   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         2354 :   gfc_get_symbol ("sizes", sub_ns, &sizes);
    1949         2354 :   sizes->ts.type = BT_INTEGER;
    1950         2354 :   sizes->ts.kind = gfc_index_integer_kind;
    1951         2354 :   sizes->attr.flavor = FL_VARIABLE;
    1952         2354 :   sizes->attr.dimension = 1;
    1953         2354 :   sizes->attr.artificial = 1;
    1954         2354 :   sizes->as = gfc_get_array_spec();
    1955         2354 :   sizes->attr.intent = INTENT_INOUT;
    1956         2354 :   sizes->as->type = AS_EXPLICIT;
    1957         2354 :   sizes->as->rank = 1;
    1958         2354 :   sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    1959         2354 :   sizes->as->upper[0] = gfc_copy_expr (rank);
    1960         2354 :   gfc_set_sym_referenced (sizes);
    1961         2354 :   gfc_commit_symbol (sizes);
    1962              : 
    1963              :   /* Create "strides(1..rank)" variable, which contains the strides per
    1964              :      dimension.  */
    1965         2354 :   gfc_get_symbol ("strides", sub_ns, &strides);
    1966         2354 :   strides->ts.type = BT_INTEGER;
    1967         2354 :   strides->ts.kind = gfc_index_integer_kind;
    1968         2354 :   strides->attr.flavor = FL_VARIABLE;
    1969         2354 :   strides->attr.dimension = 1;
    1970         2354 :   strides->attr.artificial = 1;
    1971         2354 :   strides->as = gfc_get_array_spec();
    1972         2354 :   strides->attr.intent = INTENT_INOUT;
    1973         2354 :   strides->as->type = AS_EXPLICIT;
    1974         2354 :   strides->as->rank = 1;
    1975         2354 :   strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    1976         2354 :   strides->as->upper[0] = gfc_copy_expr (rank);
    1977         2354 :   gfc_set_sym_referenced (strides);
    1978         2354 :   gfc_commit_symbol (strides);
    1979              : 
    1980              : 
    1981              :   /* Set return value to 0.  */
    1982         2354 :   last_code = gfc_get_code (EXEC_ASSIGN);
    1983         2354 :   last_code->expr1 = gfc_lval_expr_from_sym (result);
    1984         2354 :   last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
    1985         2354 :   sub_ns->code = last_code;
    1986              : 
    1987              :   /* Set:  is_contiguous = .true.  */
    1988         2354 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    1989         2354 :   last_code = last_code->next;
    1990         2354 :   last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
    1991         2354 :   last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
    1992              :                                            &gfc_current_locus, true);
    1993              : 
    1994              :   /* Set:  sizes(0) = 1.  */
    1995         2354 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    1996         2354 :   last_code = last_code->next;
    1997         2354 :   last_code->expr1 = gfc_lval_expr_from_sym (sizes);
    1998         2354 :   last_code->expr1->ref = gfc_get_ref ();
    1999         2354 :   last_code->expr1->ref->type = REF_ARRAY;
    2000         2354 :   last_code->expr1->ref->u.ar.type = AR_ELEMENT;
    2001         2354 :   last_code->expr1->ref->u.ar.dimen = 1;
    2002         2354 :   last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2003         2354 :   last_code->expr1->ref->u.ar.start[0]
    2004         2354 :                 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2005         2354 :   last_code->expr1->ref->u.ar.as = sizes->as;
    2006         2354 :   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         2354 :   iter = gfc_get_iterator ();
    2017         2354 :   iter->var = gfc_lval_expr_from_sym (idx);
    2018         2354 :   iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2019         2354 :   iter->end = gfc_copy_expr (rank);
    2020         2354 :   iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2021         2354 :   last_code->next = gfc_get_code (EXEC_DO);
    2022         2354 :   last_code = last_code->next;
    2023         2354 :   last_code->ext.iterator = iter;
    2024         2354 :   last_code->block = gfc_get_code (EXEC_DO);
    2025              : 
    2026              :   /* strides(idx) = _F._stride(array,dim=idx).  */
    2027         2354 :   last_code->block->next = gfc_get_code (EXEC_ASSIGN);
    2028         2354 :   block = last_code->block->next;
    2029              : 
    2030         2354 :   block->expr1 = gfc_lval_expr_from_sym (strides);
    2031         2354 :   block->expr1->ref = gfc_get_ref ();
    2032         2354 :   block->expr1->ref->type = REF_ARRAY;
    2033         2354 :   block->expr1->ref->u.ar.type = AR_ELEMENT;
    2034         2354 :   block->expr1->ref->u.ar.dimen = 1;
    2035         2354 :   block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2036         2354 :   block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2037         2354 :   block->expr1->ref->u.ar.as = strides->as;
    2038              : 
    2039         2354 :   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         2354 :   block->next = gfc_get_code (EXEC_ASSIGN);
    2046         2354 :   block = block->next;
    2047              : 
    2048              :   /* sizes(idx) = ...  */
    2049         2354 :   block->expr1 = gfc_lval_expr_from_sym (sizes);
    2050         2354 :   block->expr1->ref = gfc_get_ref ();
    2051         2354 :   block->expr1->ref->type = REF_ARRAY;
    2052         2354 :   block->expr1->ref->u.ar.type = AR_ELEMENT;
    2053         2354 :   block->expr1->ref->u.ar.dimen = 1;
    2054         2354 :   block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2055         2354 :   block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2056         2354 :   block->expr1->ref->u.ar.as = sizes->as;
    2057              : 
    2058         2354 :   block->expr2 = gfc_get_expr ();
    2059         2354 :   block->expr2->expr_type = EXPR_OP;
    2060         2354 :   block->expr2->value.op.op = INTRINSIC_TIMES;
    2061         2354 :   block->expr2->where = gfc_current_locus;
    2062              : 
    2063              :   /* sizes(idx-1).  */
    2064         2354 :   block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
    2065         2354 :   block->expr2->value.op.op1->ref = gfc_get_ref ();
    2066         2354 :   block->expr2->value.op.op1->ref->type = REF_ARRAY;
    2067         2354 :   block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
    2068         2354 :   block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2069         2354 :   block->expr2->value.op.op1->ref->u.ar.dimen = 1;
    2070         2354 :   block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2071         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
    2072         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
    2073         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
    2074         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    2075         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
    2076         2354 :         = gfc_lval_expr_from_sym (idx);
    2077         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
    2078         2354 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2079         2354 :   block->expr2->value.op.op1->ref->u.ar.start[0]->ts
    2080         2354 :         = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
    2081              : 
    2082              :   /* size(array, dim=idx, kind=index_kind).  */
    2083         4708 :   block->expr2->value.op.op2
    2084         2354 :         = 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         2354 :   block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
    2092         2354 :   block->expr2->ts = idx->ts;
    2093              : 
    2094              :   /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false.  */
    2095         2354 :   block->next = gfc_get_code (EXEC_IF);
    2096         2354 :   block = block->next;
    2097              : 
    2098         2354 :   block->block = gfc_get_code (EXEC_IF);
    2099         2354 :   block = block->block;
    2100              : 
    2101              :   /* if condition: strides(idx) /= sizes(idx-1).  */
    2102         2354 :   block->expr1 = gfc_get_expr ();
    2103         2354 :   block->expr1->ts.type = BT_LOGICAL;
    2104         2354 :   block->expr1->ts.kind = gfc_default_logical_kind;
    2105         2354 :   block->expr1->expr_type = EXPR_OP;
    2106         2354 :   block->expr1->where = gfc_current_locus;
    2107         2354 :   block->expr1->value.op.op = INTRINSIC_NE;
    2108              : 
    2109         2354 :   block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
    2110         2354 :   block->expr1->value.op.op1->ref = gfc_get_ref ();
    2111         2354 :   block->expr1->value.op.op1->ref->type = REF_ARRAY;
    2112         2354 :   block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2113         2354 :   block->expr1->value.op.op1->ref->u.ar.dimen = 1;
    2114         2354 :   block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2115         2354 :   block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
    2116         2354 :   block->expr1->value.op.op1->ref->u.ar.as = strides->as;
    2117              : 
    2118         2354 :   block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
    2119         2354 :   block->expr1->value.op.op2->ref = gfc_get_ref ();
    2120         2354 :   block->expr1->value.op.op2->ref->type = REF_ARRAY;
    2121         2354 :   block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
    2122         2354 :   block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
    2123         2354 :   block->expr1->value.op.op2->ref->u.ar.dimen = 1;
    2124         2354 :   block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2125         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
    2126         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
    2127         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
    2128         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
    2129         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
    2130         2354 :         = gfc_lval_expr_from_sym (idx);
    2131         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
    2132         2354 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2133         2354 :   block->expr1->value.op.op2->ref->u.ar.start[0]->ts
    2134         2354 :         = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
    2135              : 
    2136              :   /* if body: is_contiguous = .false.  */
    2137         2354 :   block->next = gfc_get_code (EXEC_ASSIGN);
    2138         2354 :   block = block->next;
    2139         2354 :   block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
    2140         2354 :   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         2354 :   gfc_get_symbol ("nelem", sub_ns, &nelem);
    2146         2354 :   nelem->ts.type = BT_INTEGER;
    2147         2354 :   nelem->ts.kind = gfc_index_integer_kind;
    2148         2354 :   nelem->attr.flavor = FL_VARIABLE;
    2149         2354 :   nelem->attr.artificial = 1;
    2150         2354 :   gfc_set_sym_referenced (nelem);
    2151         2354 :   gfc_commit_symbol (nelem);
    2152              : 
    2153              :   /* nelem = sizes (rank) - 1.  */
    2154         2354 :   last_code->next = gfc_get_code (EXEC_ASSIGN);
    2155         2354 :   last_code = last_code->next;
    2156              : 
    2157         2354 :   last_code->expr1 = gfc_lval_expr_from_sym (nelem);
    2158              : 
    2159         2354 :   last_code->expr2 = gfc_get_expr ();
    2160         2354 :   last_code->expr2->expr_type = EXPR_OP;
    2161         2354 :   last_code->expr2->value.op.op = INTRINSIC_MINUS;
    2162         2354 :   last_code->expr2->value.op.op2
    2163         2354 :         = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2164         2354 :   last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
    2165         2354 :   last_code->expr2->where = gfc_current_locus;
    2166              : 
    2167         2354 :   last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
    2168         2354 :   last_code->expr2->value.op.op1->ref = gfc_get_ref ();
    2169         2354 :   last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
    2170         2354 :   last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
    2171         2354 :   last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
    2172         2354 :   last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
    2173         2354 :   last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
    2174         2354 :   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         2354 :   if (derived->f2k_derived && derived->f2k_derived->finalizers)
    2195              :     {
    2196          442 :       gfc_finalizer *fini, *fini_elem = NULL;
    2197              : 
    2198          442 :       gfc_get_symbol ("ptr1", sub_ns, &ptr);
    2199          442 :       ptr->ts.type = BT_DERIVED;
    2200          442 :       ptr->ts.u.derived = derived;
    2201          442 :       ptr->attr.flavor = FL_VARIABLE;
    2202          442 :       ptr->attr.pointer = 1;
    2203          442 :       ptr->attr.artificial = 1;
    2204          442 :       gfc_set_sym_referenced (ptr);
    2205          442 :       gfc_commit_symbol (ptr);
    2206              : 
    2207          442 :       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          442 :       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          436 :       last_code->next = gfc_get_code (EXEC_SELECT);
    2227          436 :       last_code = last_code->next;
    2228          436 :       last_code->expr1 = gfc_copy_expr (rank);
    2229          436 :       block = NULL;
    2230              : 
    2231              : 
    2232          955 :       for (; fini; fini = fini->next)
    2233              :         {
    2234          519 :           gcc_assert (fini->proc_tree);   /* Should have been set in gfc_resolve_finalizers.  */
    2235          519 :           if (fini->proc_tree->n.sym->attr.elemental)
    2236              :             {
    2237          126 :               fini_elem = fini;
    2238          126 :               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          436 :       if (fini_elem)
    2282              :         {
    2283              :           /* CASE DEFAULT.  */
    2284          126 :           if (block)
    2285              :             {
    2286           13 :               block->block = gfc_get_code (EXEC_SELECT);
    2287           13 :               block = block->block;
    2288              :             }
    2289              :           else
    2290              :             {
    2291          113 :               block = gfc_get_code (EXEC_SELECT);
    2292          113 :               last_code->block = block;
    2293              :             }
    2294          126 :           block->ext.block.case_list = gfc_get_case ();
    2295              : 
    2296              :           /* Create loop.  */
    2297          126 :           iter = gfc_get_iterator ();
    2298          126 :           iter->var = gfc_lval_expr_from_sym (idx);
    2299          126 :           iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2300          126 :           iter->end = gfc_lval_expr_from_sym (nelem);
    2301          126 :           iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2302          126 :           block->next = gfc_get_code (EXEC_DO);
    2303          126 :           block = block->next;
    2304          126 :           block->ext.iterator = iter;
    2305          126 :           block->block = gfc_get_code (EXEC_DO);
    2306              : 
    2307              :           /* Offset calculation.  */
    2308          126 :           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          126 :           block->next
    2316          126 :                 = finalization_scalarizer (array, ptr,
    2317              :                                            gfc_lval_expr_from_sym (offset),
    2318              :                                            sub_ns);
    2319          126 :           block = block->next;
    2320              : 
    2321              :           /* CALL final_elemental (array).  */
    2322          126 :           block->next = gfc_get_code (EXEC_CALL);
    2323          126 :           block = block->next;
    2324          126 :           block->symtree = fini_elem->proc_tree;
    2325          126 :           block->resolved_sym = fini_elem->proc_sym;
    2326          126 :           block->ext.actual = gfc_get_actual_arglist ();
    2327          126 :           block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
    2328              :         }
    2329              :     }
    2330              : 
    2331         1912 : finish_assumed_rank:
    2332              : 
    2333              :   /* Finalize and deallocate allocatable components. The same manual
    2334              :      scalarization is used as above.  */
    2335              : 
    2336         2354 :   if (finalizable_comp)
    2337              :     {
    2338         1990 :       gfc_symbol *stat;
    2339         1990 :       gfc_code *block = NULL;
    2340         1990 :       gfc_expr *ptr_expr;
    2341              : 
    2342         1990 :       if (!ptr)
    2343              :         {
    2344         1912 :           gfc_get_symbol ("ptr2", sub_ns, &ptr);
    2345         1912 :           ptr->ts.type = BT_DERIVED;
    2346         1912 :           ptr->ts.u.derived = derived;
    2347         1912 :           ptr->attr.flavor = FL_VARIABLE;
    2348         1912 :           ptr->attr.pointer = 1;
    2349         1912 :           ptr->attr.artificial = 1;
    2350         1912 :           gfc_set_sym_referenced (ptr);
    2351         1912 :           gfc_commit_symbol (ptr);
    2352              :         }
    2353              : 
    2354         1990 :       gfc_get_symbol ("ignore", sub_ns, &stat);
    2355         1990 :       stat->attr.flavor = FL_VARIABLE;
    2356         1990 :       stat->attr.artificial = 1;
    2357         1990 :       stat->ts.type = BT_INTEGER;
    2358         1990 :       stat->ts.kind = gfc_default_integer_kind;
    2359         1990 :       gfc_set_sym_referenced (stat);
    2360         1990 :       gfc_commit_symbol (stat);
    2361              : 
    2362              :       /* Create loop.  */
    2363         1990 :       iter = gfc_get_iterator ();
    2364         1990 :       iter->var = gfc_lval_expr_from_sym (idx);
    2365         1990 :       iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
    2366         1990 :       iter->end = gfc_lval_expr_from_sym (nelem);
    2367         1990 :       iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
    2368         1990 :       last_code->next = gfc_get_code (EXEC_DO);
    2369         1990 :       last_code = last_code->next;
    2370         1990 :       last_code->ext.iterator = iter;
    2371         1990 :       last_code->block = gfc_get_code (EXEC_DO);
    2372              : 
    2373              :       /* Offset calculation.  */
    2374         1990 :       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         1990 :       block->next = finalization_scalarizer (array, ptr,
    2382              :                                              gfc_lval_expr_from_sym(offset),
    2383              :                                              sub_ns);
    2384         1990 :       block = block->next;
    2385              : 
    2386         1990 :       ptr_expr = gfc_lval_expr_from_sym (ptr);
    2387         5398 :       for (comp = derived->components; comp; comp = comp->next)
    2388              :         {
    2389         3408 :           if (comp == derived->components && derived->attr.extension
    2390          220 :               && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    2391           55 :             continue;
    2392              : 
    2393         3353 :           finalize_component (ptr_expr, derived, comp, stat, fini_coarray,
    2394              :                               &block, sub_ns);
    2395         3353 :           if (!last_code->block->next)
    2396            0 :             last_code->block->next = block;
    2397              :         }
    2398              : 
    2399              :     }
    2400              : 
    2401              :   /* Call the finalizer of the ancestor.  */
    2402         2354 :   if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
    2403              :     {
    2404          116 :       last_code->next = gfc_get_code (EXEC_CALL);
    2405          116 :       last_code = last_code->next;
    2406          116 :       last_code->symtree = ancestor_wrapper->symtree;
    2407          116 :       last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
    2408              : 
    2409          116 :       last_code->ext.actual = gfc_get_actual_arglist ();
    2410          116 :       last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
    2411          116 :       last_code->ext.actual->next = gfc_get_actual_arglist ();
    2412          116 :       last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
    2413          116 :       last_code->ext.actual->next->next = gfc_get_actual_arglist ();
    2414          116 :       last_code->ext.actual->next->next->expr
    2415          116 :                         = gfc_lval_expr_from_sym (fini_coarray);
    2416              :     }
    2417              : 
    2418         2354 :   gfc_free_expr (rank);
    2419         2354 :   vtab_final->initializer = gfc_lval_expr_from_sym (final);
    2420         2354 :   vtab_final->ts.interface = final;
    2421         2354 :   free (name);
    2422              : }
    2423              : 
    2424              : 
    2425              : /* Add procedure pointers for all type-bound procedures to a vtab.  */
    2426              : 
    2427              : static void
    2428        11324 : add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
    2429              : {
    2430        11324 :   gfc_symbol* super_type;
    2431              : 
    2432        11324 :   super_type = gfc_get_derived_super_type (derived);
    2433              : 
    2434        11324 :   if (super_type && (super_type != derived))
    2435              :     {
    2436              :       /* Make sure that the PPCs appear in the same order as in the parent.  */
    2437         1473 :       copy_vtab_proc_comps (super_type, vtype);
    2438              :       /* Only needed to get the PPC initializers right.  */
    2439         1473 :       add_procs_to_declared_vtab (super_type, vtype);
    2440              :     }
    2441              : 
    2442        11324 :   if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
    2443         2351 :     add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
    2444              : 
    2445        11324 :   if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
    2446           48 :     add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
    2447        11324 : }
    2448              : 
    2449              : 
    2450              : /* Find or generate the symbol for a derived type's vtab.  */
    2451              : 
    2452              : gfc_symbol *
    2453        81304 : gfc_find_derived_vtab (gfc_symbol *derived)
    2454              : {
    2455        81304 :   gfc_namespace *ns;
    2456        81304 :   gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
    2457        81304 :   gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
    2458        81304 :   gfc_gsymbol *gsym = NULL;
    2459        81304 :   gfc_symbol *dealloc = NULL, *arg = NULL;
    2460              : 
    2461        81304 :   if (derived->attr.pdt_template)
    2462              :     return NULL;
    2463              : 
    2464              :   /* Find the top-level namespace, stopping at module/submodule boundaries.
    2465              :      A submodule's namespace may have its parent pointer set to the ancestor
    2466              :      module namespace for host-association purposes; we must not escape that
    2467              :      boundary, because vtables for types defined in a submodule belong in
    2468              :      the submodule namespace, not in its parent module.  */
    2469        99048 :   for (ns = gfc_current_ns; ns; ns = ns->parent)
    2470        99048 :     if (!ns->parent
    2471        18234 :         || (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE))
    2472              :       break;
    2473              : 
    2474              :   /* If the type is a class container, use the underlying derived type.  */
    2475        81278 :   if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
    2476        10504 :     derived = gfc_get_derived_super_type (derived);
    2477              : 
    2478        10504 :   if (!derived)
    2479              :     return NULL;
    2480              : 
    2481        81278 :   if (!derived->name)
    2482              :     return NULL;
    2483              : 
    2484              :   /* Find the gsymbol for the module of use associated derived types.  */
    2485        81278 :   if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
    2486        36809 :        && !derived->attr.vtype && !derived->attr.is_class)
    2487        36809 :     gsym =  gfc_find_gsymbol (gfc_gsym_root, derived->module);
    2488              :   else
    2489              :     gsym = NULL;
    2490              : 
    2491              :   /* Work in the gsymbol namespace if the top-level namespace is a module.
    2492              :      This ensures that the vtable is unique, which is required since we use
    2493              :      its address in SELECT TYPE.  */
    2494        95251 :   gfc_namespace *module_ns = ns;
    2495        36809 :   if (gsym && gsym->ns && ns && ns->proc_name
    2496        28200 :       && ns->proc_name->attr.flavor == FL_MODULE)
    2497              :     ns = gsym->ns;
    2498              : 
    2499        58442 :   if (ns)
    2500              :     {
    2501        81278 :       char tname[GFC_MAX_SYMBOL_LEN+1];
    2502        81278 :       char *name;
    2503              : 
    2504        81278 :       get_unique_hashed_string (tname, derived);
    2505        81278 :       name = xasprintf ("__vtab_%s", tname);
    2506              : 
    2507              :       /* Look for the vtab symbol in various namespaces.  */
    2508        81278 :       if (gsym && gsym->ns)
    2509              :         {
    2510        28200 :           gfc_find_symbol (name, gsym->ns, 0, &vtab);
    2511        28200 :           if (vtab)
    2512        27767 :             ns = gsym->ns;
    2513              :         }
    2514        81278 :       if (vtab == NULL)
    2515        53511 :         gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
    2516        81278 :       if (vtab == NULL)
    2517        22463 :         gfc_find_symbol (name, ns, 0, &vtab);
    2518        81278 :       if (vtab == NULL)
    2519        10629 :         gfc_find_symbol (name, derived->ns, 0, &vtab);
    2520              :       /* If all else fails, look in the module/submodule namespace so that
    2521              :          the module variable and procedure body translations find the same
    2522              :          frontend symbol and backend decl.  */
    2523        81278 :       if (vtab == NULL && module_ns != ns)
    2524            3 :         gfc_find_symbol (name, module_ns, 0, &vtab);
    2525              : 
    2526        81278 :       if (vtab == NULL)
    2527              :         {
    2528        10611 :           gfc_get_symbol (name, ns, &vtab);
    2529        10611 :           vtab->ts.type = BT_DERIVED;
    2530        10611 :           if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
    2531              :                                &gfc_current_locus))
    2532            0 :             goto cleanup;
    2533        10611 :           vtab->attr.target = 1;
    2534        10611 :           vtab->attr.save = SAVE_IMPLICIT;
    2535        10611 :           vtab->attr.vtab = 1;
    2536        10611 :           vtab->attr.access = ACCESS_PUBLIC;
    2537        10611 :           vtab->attr.artificial = 1;
    2538        10611 :           gfc_set_sym_referenced (vtab);
    2539        10611 :           free (name);
    2540        10611 :           name = xasprintf ("__vtype_%s", tname);
    2541              : 
    2542        10611 :           gfc_find_symbol (name, ns, 0, &vtype);
    2543        10611 :           if (vtype == NULL)
    2544              :             {
    2545        10611 :               gfc_component *c;
    2546        10611 :               gfc_symbol *parent = NULL, *parent_vtab = NULL;
    2547              : 
    2548        10611 :               gfc_get_symbol (name, ns, &vtype);
    2549        10611 :               if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
    2550              :                                    &gfc_current_locus))
    2551            0 :                 goto cleanup;
    2552        10611 :               vtype->attr.access = ACCESS_PUBLIC;
    2553        10611 :               vtype->attr.vtype = 1;
    2554        10611 :               gfc_set_sym_referenced (vtype);
    2555              : 
    2556              :               /* Add component '_hash'.  */
    2557        10611 :               if (!gfc_add_component (vtype, "_hash", &c))
    2558            0 :                 goto cleanup;
    2559        10611 :               c->ts.type = BT_INTEGER;
    2560        10611 :               c->ts.kind = 4;
    2561        10611 :               c->attr.access = ACCESS_PRIVATE;
    2562        21222 :               c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
    2563        10611 :                                                  NULL, derived->hash_value);
    2564              : 
    2565              :               /* Add component '_size'.  */
    2566        10611 :               if (!gfc_add_component (vtype, "_size", &c))
    2567            0 :                 goto cleanup;
    2568        10611 :               c->ts.type = BT_INTEGER;
    2569        10611 :               c->ts.kind = gfc_size_kind;
    2570        10611 :               c->attr.access = ACCESS_PRIVATE;
    2571              :               /* Remember the derived type in ts.u.derived,
    2572              :                  so that the correct initializer can be set later on
    2573              :                  (in gfc_conv_structure).  */
    2574        10611 :               c->ts.u.derived = derived;
    2575        10611 :               c->initializer = gfc_get_int_expr (gfc_size_kind,
    2576              :                                                  NULL, 0);
    2577              : 
    2578              :               /* Add component _extends.  */
    2579        10611 :               if (!gfc_add_component (vtype, "_extends", &c))
    2580            0 :                 goto cleanup;
    2581        10611 :               c->attr.pointer = 1;
    2582        10611 :               c->attr.access = ACCESS_PRIVATE;
    2583        10611 :               if (!derived->attr.unlimited_polymorphic)
    2584         9855 :                 parent = gfc_get_derived_super_type (derived);
    2585              :               else
    2586              :                 parent = NULL;
    2587              : 
    2588         9855 :               if (parent)
    2589              :                 {
    2590         1352 :                   parent_vtab = gfc_find_derived_vtab (parent);
    2591         1352 :                   c->ts.type = BT_DERIVED;
    2592         1352 :                   c->ts.u.derived = parent_vtab->ts.u.derived;
    2593         1352 :                   c->initializer = gfc_get_expr ();
    2594         1352 :                   c->initializer->expr_type = EXPR_VARIABLE;
    2595         1352 :                   gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
    2596              :                                      0, &c->initializer->symtree);
    2597              :                 }
    2598              :               else
    2599              :                 {
    2600         9259 :                   c->ts.type = BT_DERIVED;
    2601         9259 :                   c->ts.u.derived = vtype;
    2602         9259 :                   c->initializer = gfc_get_null_expr (NULL);
    2603              :                 }
    2604              : 
    2605        10611 :               if (!derived->attr.unlimited_polymorphic
    2606         9855 :                   && derived->components == NULL
    2607         1094 :                   && !derived->attr.zero_comp)
    2608              :                 {
    2609              :                   /* At this point an error must have occurred.
    2610              :                      Prevent further errors on the vtype components.  */
    2611            4 :                   found_sym = vtab;
    2612            4 :                   goto have_vtype;
    2613              :                 }
    2614              : 
    2615              :               /* Add component _def_init.  */
    2616        10607 :               if (!gfc_add_component (vtype, "_def_init", &c))
    2617            0 :                 goto cleanup;
    2618        10607 :               c->attr.pointer = 1;
    2619        10607 :               c->attr.artificial = 1;
    2620        10607 :               c->attr.access = ACCESS_PRIVATE;
    2621        10607 :               c->ts.type = BT_DERIVED;
    2622        10607 :               c->ts.u.derived = derived;
    2623        10607 :               if (derived->attr.unlimited_polymorphic
    2624         9851 :                   || derived->attr.abstract)
    2625         1067 :                 c->initializer = gfc_get_null_expr (NULL);
    2626              :               else
    2627              :                 {
    2628              :                   /* Construct default initialization variable.  */
    2629         9540 :                   free (name);
    2630         9540 :                   name = xasprintf ("__def_init_%s", tname);
    2631         9540 :                   gfc_get_symbol (name, ns, &def_init);
    2632         9540 :                   def_init->attr.target = 1;
    2633         9540 :                   def_init->attr.artificial = 1;
    2634         9540 :                   def_init->attr.save = SAVE_IMPLICIT;
    2635         9540 :                   def_init->attr.access = ACCESS_PUBLIC;
    2636         9540 :                   def_init->attr.flavor = FL_VARIABLE;
    2637         9540 :                   gfc_set_sym_referenced (def_init);
    2638         9540 :                   def_init->ts.type = BT_DERIVED;
    2639         9540 :                   def_init->ts.u.derived = derived;
    2640         9540 :                   def_init->value = gfc_default_initializer (&def_init->ts);
    2641              : 
    2642         9540 :                   c->initializer = gfc_lval_expr_from_sym (def_init);
    2643              :                 }
    2644              : 
    2645              :               /* Add component _copy.  */
    2646        10607 :               if (!gfc_add_component (vtype, "_copy", &c))
    2647            0 :                 goto cleanup;
    2648        10607 :               c->attr.proc_pointer = 1;
    2649        10607 :               c->attr.access = ACCESS_PRIVATE;
    2650        10607 :               c->attr.artificial = 1;
    2651        10607 :               c->tb = XCNEW (gfc_typebound_proc);
    2652        10607 :               c->tb->ppc = 1;
    2653        10607 :               if (derived->attr.unlimited_polymorphic
    2654         9851 :                   || derived->attr.abstract)
    2655         1067 :                 c->initializer = gfc_get_null_expr (NULL);
    2656              :               else
    2657              :                 {
    2658              :                   /* Set up namespace.  */
    2659         9540 :                   gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
    2660         9540 :                   sub_ns->sibling = ns->contained;
    2661         9540 :                   ns->contained = sub_ns;
    2662         9540 :                   sub_ns->resolved = 1;
    2663              :                   /* Set up procedure symbol.  */
    2664         9540 :                   free (name);
    2665         9540 :                   name = xasprintf ("__copy_%s", tname);
    2666         9540 :                   gfc_get_symbol (name, sub_ns, &copy);
    2667         9540 :                   sub_ns->proc_name = copy;
    2668         9540 :                   copy->attr.flavor = FL_PROCEDURE;
    2669         9540 :                   copy->attr.subroutine = 1;
    2670         9540 :                   copy->attr.pure = 1;
    2671         9540 :                   copy->attr.artificial = 1;
    2672         9540 :                   copy->attr.if_source = IFSRC_DECL;
    2673              :                   /* This is elemental so that arrays are automatically
    2674              :                      treated correctly by the scalarizer.  */
    2675         9540 :                   copy->attr.elemental = 1;
    2676         9540 :                   if (ns->proc_name->attr.flavor == FL_MODULE)
    2677         7819 :                     copy->module = ns->proc_name->name;
    2678         9540 :                   gfc_set_sym_referenced (copy);
    2679              :                   /* Set up formal arguments.  */
    2680         9540 :                   gfc_get_symbol ("src", sub_ns, &src);
    2681         9540 :                   src->ts.type = BT_DERIVED;
    2682         9540 :                   src->ts.u.derived = derived;
    2683         9540 :                   src->attr.flavor = FL_VARIABLE;
    2684         9540 :                   src->attr.dummy = 1;
    2685         9540 :                   src->attr.artificial = 1;
    2686         9540 :                   src->attr.intent = INTENT_IN;
    2687         9540 :                   gfc_set_sym_referenced (src);
    2688         9540 :                   copy->formal = gfc_get_formal_arglist ();
    2689         9540 :                   copy->formal->sym = src;
    2690         9540 :                   gfc_get_symbol ("dst", sub_ns, &dst);
    2691         9540 :                   dst->ts.type = BT_DERIVED;
    2692         9540 :                   dst->ts.u.derived = derived;
    2693         9540 :                   dst->attr.flavor = FL_VARIABLE;
    2694         9540 :                   dst->attr.dummy = 1;
    2695         9540 :                   dst->attr.artificial = 1;
    2696         9540 :                   dst->attr.intent = INTENT_INOUT;
    2697         9540 :                   gfc_set_sym_referenced (dst);
    2698         9540 :                   copy->formal->next = gfc_get_formal_arglist ();
    2699         9540 :                   copy->formal->next->sym = dst;
    2700              :                   /* Set up code.  */
    2701         9540 :                   sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
    2702         9540 :                   sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
    2703         9540 :                   sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
    2704              :                   /* Set initializer.  */
    2705         9540 :                   c->initializer = gfc_lval_expr_from_sym (copy);
    2706         9540 :                   c->ts.interface = copy;
    2707              :                 }
    2708              : 
    2709              :               /* Add component _final, which contains a procedure pointer to
    2710              :                  a wrapper which handles both the freeing of allocatable
    2711              :                  components and the calls to finalization subroutines.
    2712              :                  Note: The actual wrapper function can only be generated
    2713              :                  at resolution time.  */
    2714        10607 :               if (!gfc_add_component (vtype, "_final", &c))
    2715            0 :                 goto cleanup;
    2716        10607 :               c->attr.proc_pointer = 1;
    2717        10607 :               c->attr.access = ACCESS_PRIVATE;
    2718        10607 :               c->attr.artificial = 1;
    2719        10607 :               c->tb = XCNEW (gfc_typebound_proc);
    2720        10607 :               c->tb->ppc = 1;
    2721        10607 :               generate_finalization_wrapper (derived, ns, tname, c);
    2722              : 
    2723              :               /* Add component _deallocate.  */
    2724        10607 :               if (!gfc_add_component (vtype, "_deallocate", &c))
    2725            0 :                 goto cleanup;
    2726        10607 :               c->attr.proc_pointer = 1;
    2727        10607 :               c->attr.access = ACCESS_PRIVATE;
    2728        10607 :               c->attr.artificial = 1;
    2729        10607 :               c->tb = XCNEW (gfc_typebound_proc);
    2730        10607 :               c->tb->ppc = 1;
    2731        10607 :               if (derived->attr.unlimited_polymorphic || derived->attr.abstract
    2732         9540 :                   || !derived->attr.recursive)
    2733        10352 :                 c->initializer = gfc_get_null_expr (NULL);
    2734              :               else
    2735              :                 {
    2736              :                   /* Set up namespace.  */
    2737          255 :                   gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
    2738              : 
    2739          255 :                   sub_ns->sibling = ns->contained;
    2740          255 :                   ns->contained = sub_ns;
    2741          255 :                   sub_ns->resolved = 1;
    2742              :                   /* Set up procedure symbol.  */
    2743          255 :                   free (name);
    2744          255 :                   name = xasprintf ("__deallocate_%s", tname);
    2745          255 :                   gfc_get_symbol (name, sub_ns, &dealloc);
    2746          255 :                   sub_ns->proc_name = dealloc;
    2747          255 :                   dealloc->attr.flavor = FL_PROCEDURE;
    2748          255 :                   dealloc->attr.subroutine = 1;
    2749          255 :                   dealloc->attr.pure = 1;
    2750          255 :                   dealloc->attr.artificial = 1;
    2751          255 :                   dealloc->attr.if_source = IFSRC_DECL;
    2752              : 
    2753          255 :                   if (ns->proc_name->attr.flavor == FL_MODULE)
    2754          173 :                     dealloc->module = ns->proc_name->name;
    2755          255 :                   gfc_set_sym_referenced (dealloc);
    2756              :                   /* Set up formal argument.  */
    2757          255 :                   gfc_get_symbol ("arg", sub_ns, &arg);
    2758          255 :                   arg->ts.type = BT_DERIVED;
    2759          255 :                   arg->ts.u.derived = derived;
    2760          255 :                   arg->attr.flavor = FL_VARIABLE;
    2761          255 :                   arg->attr.dummy = 1;
    2762          255 :                   arg->attr.artificial = 1;
    2763          255 :                   arg->attr.intent = INTENT_INOUT;
    2764          255 :                   arg->attr.dimension = 1;
    2765          255 :                   arg->attr.allocatable = 1;
    2766          255 :                   arg->as = gfc_get_array_spec();
    2767          255 :                   arg->as->type = AS_ASSUMED_SHAPE;
    2768          255 :                   arg->as->rank = 1;
    2769          255 :                   arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
    2770              :                                                         NULL, 1);
    2771          255 :                   gfc_set_sym_referenced (arg);
    2772          255 :                   dealloc->formal = gfc_get_formal_arglist ();
    2773          255 :                   dealloc->formal->sym = arg;
    2774              :                   /* Set up code.  */
    2775          255 :                   sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
    2776          255 :                   sub_ns->code->ext.alloc.list = gfc_get_alloc ();
    2777          255 :                   sub_ns->code->ext.alloc.list->expr
    2778          255 :                                 = gfc_lval_expr_from_sym (arg);
    2779              :                   /* Set initializer.  */
    2780          255 :                   c->initializer = gfc_lval_expr_from_sym (dealloc);
    2781          255 :                   c->ts.interface = dealloc;
    2782              :                 }
    2783              : 
    2784              :               /* Add procedure pointers for type-bound procedures.  */
    2785        10607 :               if (!derived->attr.unlimited_polymorphic)
    2786         9851 :                 add_procs_to_declared_vtab (derived, vtype);
    2787              :           }
    2788              : 
    2789            0 : have_vtype:
    2790        10611 :           vtab->ts.u.derived = vtype;
    2791        10611 :           vtab->value = gfc_default_initializer (&vtab->ts);
    2792              :         }
    2793        81278 :       free (name);
    2794              :     }
    2795              : 
    2796        81278 :   found_sym = vtab;
    2797              : 
    2798        81278 : cleanup:
    2799              :   /* It is unexpected to have some symbols added at resolution or code
    2800              :      generation time. We commit the changes in order to keep a clean state.  */
    2801        81278 :   if (found_sym)
    2802              :     {
    2803        81278 :       gfc_commit_symbol (vtab);
    2804        81278 :       if (vtype)
    2805        10611 :         gfc_commit_symbol (vtype);
    2806        81278 :       if (def_init)
    2807         9540 :         gfc_commit_symbol (def_init);
    2808        81278 :       if (copy)
    2809         9540 :         gfc_commit_symbol (copy);
    2810        81278 :       if (src)
    2811         9540 :         gfc_commit_symbol (src);
    2812        81278 :       if (dst)
    2813         9540 :         gfc_commit_symbol (dst);
    2814        81278 :       if (dealloc)
    2815          255 :         gfc_commit_symbol (dealloc);
    2816        81278 :       if (arg)
    2817          255 :         gfc_commit_symbol (arg);
    2818              :     }
    2819              :   else
    2820            0 :     gfc_undo_symbols ();
    2821              : 
    2822              :   return found_sym;
    2823              : }
    2824              : 
    2825              : 
    2826              : /* Check if a derived type is finalizable. That is the case if it
    2827              :    (1) has a FINAL subroutine or
    2828              :    (2) has a nonpointer nonallocatable component of finalizable type.
    2829              :    If it is finalizable, return an expression containing the
    2830              :    finalization wrapper.  */
    2831              : 
    2832              : bool
    2833       104199 : gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
    2834              : {
    2835       104199 :   gfc_symbol *vtab;
    2836       104199 :   gfc_component *c;
    2837              : 
    2838              :   /* (1) Check for FINAL subroutines.  */
    2839       104199 :   if (derived->f2k_derived && derived->f2k_derived->finalizers)
    2840         6927 :     goto yes;
    2841              : 
    2842              :   /* (2) Check for components of finalizable type.  */
    2843       250362 :   for (c = derived->components; c; c = c->next)
    2844       153652 :     if (c->ts.type == BT_DERIVED
    2845        26565 :         && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
    2846       162011 :         && gfc_is_finalizable (c->ts.u.derived, NULL))
    2847          562 :       goto yes;
    2848              : 
    2849              :   return false;
    2850              : 
    2851         7489 : yes:
    2852              :   /* Make sure vtab is generated.  */
    2853         7489 :   vtab = gfc_find_derived_vtab (derived);
    2854         7489 :   if (final_expr)
    2855              :     {
    2856              :       /* Return finalizer expression.  */
    2857          954 :       gfc_component *final;
    2858          954 :       final = vtab->ts.u.derived->components->next->next->next->next->next;
    2859          954 :       gcc_assert (strcmp (final->name, "_final") == 0);
    2860          954 :       gcc_assert (final->initializer
    2861              :                   && final->initializer->expr_type != EXPR_NULL);
    2862          954 :       *final_expr = final->initializer;
    2863              :     }
    2864              :   return true;
    2865              : }
    2866              : 
    2867              : 
    2868              : bool
    2869       522883 : gfc_may_be_finalized (gfc_typespec ts)
    2870              : {
    2871       522883 :   return (ts.type == BT_CLASS || (ts.type == BT_DERIVED
    2872        70393 :           && ts.u.derived && gfc_is_finalizable (ts.u.derived, NULL)));
    2873              : }
    2874              : 
    2875              : 
    2876              : /* Find (or generate) the symbol for an intrinsic type's vtab.  This is
    2877              :    needed to support unlimited polymorphism.  */
    2878              : 
    2879              : static gfc_symbol *
    2880         6784 : find_intrinsic_vtab (gfc_typespec *ts)
    2881              : {
    2882         6784 :   gfc_namespace *ns;
    2883         6784 :   gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
    2884         6784 :   gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
    2885              : 
    2886              :   /* Find the top-level namespace.  */
    2887         9647 :   for (ns = gfc_current_ns; ns; ns = ns->parent)
    2888         9647 :     if (!ns->parent)
    2889              :       break;
    2890              : 
    2891         6784 :   if (ns)
    2892              :     {
    2893         6784 :       char tname[GFC_MAX_SYMBOL_LEN+1];
    2894         6784 :       char *name;
    2895              : 
    2896              :       /* Encode all types as TYPENAME_KIND_ including especially character
    2897              :          arrays, whose length is now consistently stored in the _len component
    2898              :          of the class-variable.  */
    2899         6784 :       sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
    2900         6784 :       name = xasprintf ("__vtab_%s", tname);
    2901              : 
    2902              :       /* Look for the vtab symbol in the top-level namespace only.  */
    2903         6784 :       gfc_find_symbol (name, ns, 0, &vtab);
    2904              : 
    2905         6784 :       if (vtab == NULL)
    2906              :         {
    2907          931 :           gfc_get_symbol (name, ns, &vtab);
    2908          931 :           vtab->ts.type = BT_DERIVED;
    2909          931 :           if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
    2910              :                                &gfc_current_locus))
    2911            0 :             goto cleanup;
    2912          931 :           vtab->attr.target = 1;
    2913          931 :           vtab->attr.save = SAVE_IMPLICIT;
    2914          931 :           vtab->attr.vtab = 1;
    2915          931 :           vtab->attr.access = ACCESS_PUBLIC;
    2916          931 :           gfc_set_sym_referenced (vtab);
    2917          931 :           free (name);
    2918          931 :           name = xasprintf ("__vtype_%s", tname);
    2919              : 
    2920          931 :           gfc_find_symbol (name, ns, 0, &vtype);
    2921          931 :           if (vtype == NULL)
    2922              :             {
    2923          931 :               gfc_component *c;
    2924          931 :               int hash;
    2925          931 :               gfc_namespace *sub_ns;
    2926          931 :               gfc_namespace *contained;
    2927          931 :               gfc_expr *e;
    2928          931 :               size_t e_size;
    2929              : 
    2930          931 :               gfc_get_symbol (name, ns, &vtype);
    2931          931 :               if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
    2932              :                                    &gfc_current_locus))
    2933            0 :                 goto cleanup;
    2934          931 :               vtype->attr.access = ACCESS_PUBLIC;
    2935          931 :               vtype->attr.vtype = 1;
    2936          931 :               gfc_set_sym_referenced (vtype);
    2937              : 
    2938              :               /* Add component '_hash'.  */
    2939          931 :               if (!gfc_add_component (vtype, "_hash", &c))
    2940            0 :                 goto cleanup;
    2941          931 :               c->ts.type = BT_INTEGER;
    2942          931 :               c->ts.kind = 4;
    2943          931 :               c->attr.access = ACCESS_PRIVATE;
    2944          931 :               hash = gfc_intrinsic_hash_value (ts);
    2945          931 :               c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
    2946              :                                                  NULL, hash);
    2947              : 
    2948              :               /* Add component '_size'.  */
    2949          931 :               if (!gfc_add_component (vtype, "_size", &c))
    2950            0 :                 goto cleanup;
    2951          931 :               c->ts.type = BT_INTEGER;
    2952          931 :               c->ts.kind = gfc_size_kind;
    2953          931 :               c->attr.access = ACCESS_PRIVATE;
    2954              : 
    2955              :               /* Build a minimal expression to make use of
    2956              :                  target-memory.cc/gfc_element_size for 'size'.  Special handling
    2957              :                  for character arrays, that are not constant sized: to support
    2958              :                  len (str) * kind, only the kind information is stored in the
    2959              :                  vtab.  */
    2960          931 :               e = gfc_get_expr ();
    2961          931 :               e->ts = *ts;
    2962          931 :               e->expr_type = EXPR_VARIABLE;
    2963          931 :               if (ts->type == BT_CHARACTER)
    2964          263 :                 e_size = ts->kind;
    2965              :               else
    2966          668 :                 gfc_element_size (e, &e_size);
    2967          931 :               c->initializer = gfc_get_int_expr (gfc_size_kind,
    2968              :                                                  NULL,
    2969              :                                                  e_size);
    2970          931 :               gfc_free_expr (e);
    2971              : 
    2972              :               /* Add component _extends.  */
    2973          931 :               if (!gfc_add_component (vtype, "_extends", &c))
    2974            0 :                 goto cleanup;
    2975          931 :               c->attr.pointer = 1;
    2976          931 :               c->attr.access = ACCESS_PRIVATE;
    2977          931 :               c->ts.type = BT_VOID;
    2978          931 :               c->initializer = gfc_get_null_expr (NULL);
    2979              : 
    2980              :               /* Add component _def_init.  */
    2981          931 :               if (!gfc_add_component (vtype, "_def_init", &c))
    2982            0 :                 goto cleanup;
    2983          931 :               c->attr.pointer = 1;
    2984          931 :               c->attr.access = ACCESS_PRIVATE;
    2985          931 :               c->ts.type = BT_VOID;
    2986          931 :               c->initializer = gfc_get_null_expr (NULL);
    2987              : 
    2988              :               /* Add component _copy.  */
    2989          931 :               if (!gfc_add_component (vtype, "_copy", &c))
    2990            0 :                 goto cleanup;
    2991          931 :               c->attr.proc_pointer = 1;
    2992          931 :               c->attr.access = ACCESS_PRIVATE;
    2993          931 :               c->attr.artificial = 1;
    2994          931 :               c->tb = XCNEW (gfc_typebound_proc);
    2995          931 :               c->tb->ppc = 1;
    2996              : 
    2997          931 :               free (name);
    2998          931 :               if (ts->type != BT_CHARACTER)
    2999          668 :                 name = xasprintf ("__copy_%s", tname);
    3000              :               else
    3001              :                 {
    3002              :                   /* __copy is always the same for characters.
    3003              :                      Check to see if copy function already exists.  */
    3004          263 :                   name = xasprintf ("__copy_character_%d", ts->kind);
    3005          263 :                   contained = ns->contained;
    3006         1328 :                   for (; contained; contained = contained->sibling)
    3007         1065 :                     if (contained->proc_name
    3008         1065 :                         && strcmp (name, contained->proc_name->name) == 0)
    3009              :                       {
    3010            0 :                         copy = contained->proc_name;
    3011            0 :                         goto got_char_copy;
    3012              :                       }
    3013              :                 }
    3014              : 
    3015              :               /* Set up namespace.  */
    3016          931 :               sub_ns = gfc_get_namespace (ns, 0);
    3017          931 :               sub_ns->sibling = ns->contained;
    3018          931 :               ns->contained = sub_ns;
    3019          931 :               sub_ns->resolved = 1;
    3020              :               /* Set up procedure symbol.  */
    3021          931 :               gfc_get_symbol (name, sub_ns, &copy);
    3022          931 :               sub_ns->proc_name = copy;
    3023          931 :               copy->attr.flavor = FL_PROCEDURE;
    3024          931 :               copy->attr.subroutine = 1;
    3025          931 :               copy->attr.pure = 1;
    3026          931 :               copy->attr.if_source = IFSRC_DECL;
    3027              :               /* This is elemental so that arrays are automatically
    3028              :                  treated correctly by the scalarizer.  */
    3029          931 :               copy->attr.elemental = 1;
    3030          931 :               if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
    3031          205 :                 copy->module = ns->proc_name->name;
    3032          931 :               gfc_set_sym_referenced (copy);
    3033              :               /* Set up formal arguments.  */
    3034          931 :               gfc_get_symbol ("src", sub_ns, &src);
    3035          931 :               src->ts.type = ts->type;
    3036          931 :               src->ts.kind = ts->kind;
    3037          931 :               src->attr.flavor = FL_VARIABLE;
    3038          931 :               src->attr.dummy = 1;
    3039          931 :               src->attr.intent = INTENT_IN;
    3040          931 :               gfc_set_sym_referenced (src);
    3041          931 :               copy->formal = gfc_get_formal_arglist ();
    3042          931 :               copy->formal->sym = src;
    3043          931 :               gfc_get_symbol ("dst", sub_ns, &dst);
    3044          931 :               dst->ts.type = ts->type;
    3045          931 :               dst->ts.kind = ts->kind;
    3046          931 :               dst->attr.flavor = FL_VARIABLE;
    3047          931 :               dst->attr.dummy = 1;
    3048          931 :               dst->attr.intent = INTENT_INOUT;
    3049          931 :               gfc_set_sym_referenced (dst);
    3050          931 :               copy->formal->next = gfc_get_formal_arglist ();
    3051          931 :               copy->formal->next->sym = dst;
    3052              :               /* Set up code.  */
    3053          931 :               sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
    3054          931 :               sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
    3055          931 :               sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
    3056          931 :             got_char_copy:
    3057              :               /* Set initializer.  */
    3058          931 :               c->initializer = gfc_lval_expr_from_sym (copy);
    3059          931 :               c->ts.interface = copy;
    3060              : 
    3061              :               /* Add component _final.  */
    3062          931 :               if (!gfc_add_component (vtype, "_final", &c))
    3063            0 :                 goto cleanup;
    3064          931 :               c->attr.proc_pointer = 1;
    3065          931 :               c->attr.access = ACCESS_PRIVATE;
    3066          931 :               c->attr.artificial = 1;
    3067          931 :               c->tb = XCNEW (gfc_typebound_proc);
    3068          931 :               c->tb->ppc = 1;
    3069          931 :               c->initializer = gfc_get_null_expr (NULL);
    3070              :             }
    3071          931 :           vtab->ts.u.derived = vtype;
    3072          931 :           vtab->value = gfc_default_initializer (&vtab->ts);
    3073              :         }
    3074         6784 :       free (name);
    3075              :     }
    3076              : 
    3077         6784 :   found_sym = vtab;
    3078              : 
    3079         6784 : cleanup:
    3080              :   /* It is unexpected to have some symbols added at resolution or code
    3081              :      generation time. We commit the changes in order to keep a clean state.  */
    3082         6784 :   if (found_sym)
    3083              :     {
    3084         6784 :       gfc_commit_symbol (vtab);
    3085         6784 :       if (vtype)
    3086          931 :         gfc_commit_symbol (vtype);
    3087         6784 :       if (copy)
    3088          931 :         gfc_commit_symbol (copy);
    3089         6784 :       if (src)
    3090          931 :         gfc_commit_symbol (src);
    3091         6784 :       if (dst)
    3092          931 :         gfc_commit_symbol (dst);
    3093              :     }
    3094              :   else
    3095            0 :     gfc_undo_symbols ();
    3096              : 
    3097         6784 :   return found_sym;
    3098              : }
    3099              : 
    3100              : 
    3101              : /*  Find (or generate) a vtab for an arbitrary type (derived or intrinsic).  */
    3102              : 
    3103              : gfc_symbol *
    3104        20188 : gfc_find_vtab (gfc_typespec *ts)
    3105              : {
    3106        20188 :   switch (ts->type)
    3107              :     {
    3108              :     case BT_UNKNOWN:
    3109              :       return NULL;
    3110         8115 :     case BT_DERIVED:
    3111         8115 :       return gfc_find_derived_vtab (ts->u.derived);
    3112         5207 :     case BT_CLASS:
    3113         5207 :       if (ts->u.derived->attr.is_class
    3114         5203 :           && ts->u.derived->components
    3115         5203 :           && ts->u.derived->components->ts.u.derived)
    3116         5203 :         return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
    3117              :       else
    3118              :         return NULL;
    3119         6784 :     default:
    3120         6784 :       return find_intrinsic_vtab (ts);
    3121              :     }
    3122              : }
    3123              : 
    3124              : 
    3125              : /* General worker function to find either a type-bound procedure or a
    3126              :    type-bound user operator.  */
    3127              : 
    3128              : static gfc_symtree*
    3129       469770 : find_typebound_proc_uop (gfc_symbol* derived, bool* t,
    3130              :                          const char* name, bool noaccess, bool uop,
    3131              :                          locus* where)
    3132              : {
    3133       469770 :   gfc_symtree* res;
    3134       469770 :   gfc_symtree* root;
    3135              : 
    3136              :   /* Set default to failure.  */
    3137       469770 :   if (t)
    3138       449107 :     *t = false;
    3139              : 
    3140       469770 :   if (derived->f2k_derived)
    3141              :     /* Set correct symbol-root.  */
    3142       354036 :     root = (uop ? derived->f2k_derived->tb_uop_root
    3143              :                 : derived->f2k_derived->tb_sym_root);
    3144              :   else
    3145              :     return NULL;
    3146              : 
    3147              :   /* Try to find it in the current type's namespace.  */
    3148       354036 :   res = gfc_find_symtree (root, name);
    3149       354036 :   if (res && res->n.tb && !res->n.tb->error)
    3150              :     {
    3151              :       /* We found one.  */
    3152        10674 :       if (t)
    3153         6098 :         *t = true;
    3154              : 
    3155        10674 :       if (!noaccess && derived->attr.use_assoc
    3156         3487 :           && res->n.tb->access == ACCESS_PRIVATE)
    3157              :         {
    3158            3 :           if (where)
    3159            2 :             gfc_error ("%qs of %qs is PRIVATE at %L",
    3160              :                        name, derived->name, where);
    3161            3 :           if (t)
    3162            3 :             *t = false;
    3163              :         }
    3164              : 
    3165        10674 :       return res;
    3166              :     }
    3167              : 
    3168              :   /* Otherwise, recurse on parent type if derived is an extension.  */
    3169       343362 :   if (derived->attr.extension)
    3170              :     {
    3171        45443 :       gfc_symbol* super_type;
    3172        45443 :       super_type = gfc_get_derived_super_type (derived);
    3173        45443 :       gcc_assert (super_type);
    3174              : 
    3175        45443 :       return find_typebound_proc_uop (super_type, t, name,
    3176        45443 :                                       noaccess, uop, where);
    3177              :     }
    3178              : 
    3179              :   /* Nothing found.  */
    3180              :   return NULL;
    3181              : }
    3182              : 
    3183              : 
    3184              : /* Find a type-bound procedure or user operator by name for a derived-type
    3185              :    (looking recursively through the super-types).  */
    3186              : 
    3187              : gfc_symtree*
    3188       424081 : gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
    3189              :                          const char* name, bool noaccess, locus* where)
    3190              : {
    3191       424081 :   return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
    3192              : }
    3193              : 
    3194              : gfc_symtree*
    3195          246 : gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
    3196              :                             const char* name, bool noaccess, locus* where)
    3197              : {
    3198          246 :   return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
    3199              : }
    3200              : 
    3201              : 
    3202              : /* Find a type-bound intrinsic operator looking recursively through the
    3203              :    super-type hierarchy.  */
    3204              : 
    3205              : gfc_typebound_proc*
    3206        22766 : gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
    3207              :                                  gfc_intrinsic_op op, bool noaccess,
    3208              :                                  locus* where)
    3209              : {
    3210        22766 :   gfc_typebound_proc* res;
    3211              : 
    3212              :   /* Set default to failure.  */
    3213        22766 :   if (t)
    3214        22765 :     *t = false;
    3215              : 
    3216              :   /* Try to find it in the current type's namespace.  */
    3217        22766 :   if (derived->f2k_derived)
    3218        18765 :     res = derived->f2k_derived->tb_op[op];
    3219              :   else
    3220              :     res = NULL;
    3221              : 
    3222              :   /* Check access.  */
    3223        18765 :   if (res && !res->error)
    3224              :     {
    3225              :       /* We found one.  */
    3226          898 :       if (t)
    3227          897 :         *t = true;
    3228              : 
    3229          898 :       if (!noaccess && derived->attr.use_assoc
    3230          755 :           && res->access == ACCESS_PRIVATE)
    3231              :         {
    3232            2 :           if (where)
    3233            0 :             gfc_error ("%qs of %qs is PRIVATE at %L",
    3234              :                        gfc_op2string (op), derived->name, where);
    3235            2 :           if (t)
    3236            2 :             *t = false;
    3237              :         }
    3238              : 
    3239          898 :       return res;
    3240              :     }
    3241              : 
    3242              :   /* Otherwise, recurse on parent type if derived is an extension.  */
    3243        21868 :   if (derived->attr.extension)
    3244              :     {
    3245          839 :       gfc_symbol* super_type;
    3246          839 :       super_type = gfc_get_derived_super_type (derived);
    3247          839 :       gcc_assert (super_type);
    3248              : 
    3249          839 :       return gfc_find_typebound_intrinsic_op (super_type, t, op,
    3250          839 :                                               noaccess, where);
    3251              :     }
    3252              : 
    3253              :   /* Nothing found.  */
    3254              :   return NULL;
    3255              : }
    3256              : 
    3257              : 
    3258              : /* Get a typebound-procedure symtree or create and insert it if not yet
    3259              :    present.  This is like a very simplified version of gfc_get_sym_tree for
    3260              :    tbp-symtrees rather than regular ones.  */
    3261              : 
    3262              : gfc_symtree*
    3263         9234 : gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
    3264              : {
    3265         9234 :   gfc_symtree *result = gfc_find_symtree (*root, name);
    3266         9234 :   return result ? result : gfc_new_symtree (root, name);
    3267              : }
        

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.