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