int current_part_dimension, n_components, seen_part_dimension, dim;
gfc_ref *ref, **prev, *array_ref;
bool equal_length;
+ gfc_symbol *last_pdt = NULL;
for (ref = expr->ref; ref; ref = ref->next)
if (ref->type == REF_ARRAY && ref->u.ar.as == NULL)
n_components = 0;
array_ref = NULL;
+ if (expr->expr_type == EXPR_VARIABLE
+ && expr->symtree->n.sym->ts.type == BT_DERIVED
+ && expr->symtree->n.sym->ts.u.derived->attr.pdt_type)
+ last_pdt = expr->symtree->n.sym->ts.u.derived;
+
for (ref = expr->ref; ref; ref = ref->next)
{
switch (ref->type)
}
}
+ /* Sometimes the component in a component reference is that of the
+ pdt_template. Point to the component of pdt_type instead. This
+ ensures that the component gets a backend_decl in translation. */
+ if (last_pdt)
+ {
+ gfc_component *cmp = last_pdt->components;
+ for (; cmp; cmp = cmp->next)
+ if (!strcmp (cmp->name, ref->u.c.component->name))
+ {
+ ref->u.c.component = cmp;
+ break;
+ }
+ ref->u.c.sym = last_pdt;
+ }
+
+ /* Convert pdt_templates, if necessary, and update 'last_pdt'. */
+ if (ref->u.c.component->ts.type == BT_DERIVED)
+ {
+ if (ref->u.c.component->ts.u.derived->attr.pdt_template)
+ {
+ if (gfc_get_pdt_instance (ref->u.c.component->param_list,
+ &ref->u.c.component->ts.u.derived,
+ NULL) != MATCH_YES)
+ return false;
+ last_pdt = ref->u.c.component->ts.u.derived;
+ }
+ else if (ref->u.c.component->ts.u.derived->attr.pdt_type)
+ last_pdt = ref->u.c.component->ts.u.derived;
+ else
+ last_pdt = NULL;
+ }
+
n_components++;
break;
--- /dev/null
+! { dg-do run }
+!
+! Contributed by FortranFan at https://groups.google.com/g/comp.lang.fortran/c/NDE6JKTFbNU
+!
+ integer, parameter :: parm = 42
+ type :: t(ell)
+ integer, len :: ell
+ integer :: i
+ end type
+
+ type :: u
+ type(t(ell=:)), allocatable :: x
+ end type
+
+ type(t(ell=:)), allocatable :: foo
+ type(u) :: bar
+
+ allocate( t(ell = parm) :: foo )
+ foo%i = 2 * foo%ell
+
+ bar = u (foo) ! Gave: Cannot convert TYPE(Pdtt) to TYPE(t)
+
+ if (bar%x%ell /= parm) stop 1 ! Then these component references failed in
+ if (bar%x%i /= 2 * parm) stop 2 ! translation.
+end