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