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