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