&& CLASS_DATA (e->symtree->n.sym)
&& !CLASS_DATA (e->symtree->n.sym)->attr.dimension
&& (e->ref == NULL
- || (strcmp (e->ref->u.c.component->name, "_data") == 0
+ || (e->ref->type == REF_COMPONENT
+ && strcmp (e->ref->u.c.component->name, "_data") == 0
&& e->ref->next == NULL)))
return true;
&& CLASS_DATA (ref->u.c.component)
&& !CLASS_DATA (ref->u.c.component)->attr.dimension
&& (ref->next == NULL
- || (strcmp (ref->next->u.c.component->name, "_data") == 0
+ || (ref->next->type == REF_COMPONENT
+ && strcmp (ref->next->u.c.component->name, "_data") == 0
&& ref->next->next == NULL)))
return true;
}
int n;
bool maybe_workshare = false;
symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
+ bool is_poly_assign;
/* Assignment of the form lhs = rhs. */
gfc_start_block (&block);
|| gfc_is_alloc_class_scalar_function (expr2)))
expr2->must_finalize = 1;
+ /* Checking whether a class assignment is desired is quite complicated and
+ needed at two locations, so do it once only before the information is
+ needed. */
+ lhs_attr = gfc_expr_attr (expr1);
+ is_poly_assign = (use_vptr_copy || lhs_attr.pointer
+ || (lhs_attr.allocatable && !lhs_attr.dimension))
+ && (expr1->ts.type == BT_CLASS
+ || gfc_is_class_array_ref (expr1, NULL)
+ || gfc_is_class_scalar_expr (expr1)
+ || gfc_is_class_array_ref (expr2, NULL)
+ || gfc_is_class_scalar_expr (expr2));
+
+
/* Only analyze the expressions for coarray properties, when in coarray-lib
mode. */
if (flag_coarray == GFC_FCOARRAY_LIB)
if (rss == gfc_ss_terminator)
/* The rhs is scalar. Add a ss for the expression. */
rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
+ /* When doing a class assign, then the handle to the rhs needs to be a
+ pointer to allow for polymorphism. */
+ if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
+ rss->info->type = GFC_SS_REFERENCE;
/* Associate the SS with the loop. */
gfc_add_ss_to_loop (&loop, lss);
gfc_add_block_to_block (&loop.post, &rse.post);
}
- lhs_attr = gfc_expr_attr (expr1);
- if ((use_vptr_copy || lhs_attr.pointer
- || (lhs_attr.allocatable && !lhs_attr.dimension))
- && (expr1->ts.type == BT_CLASS
- || (gfc_is_class_array_ref (expr1, NULL)
- || gfc_is_class_scalar_expr (expr1))
- || (gfc_is_class_array_ref (expr2, NULL)
- || gfc_is_class_scalar_expr (expr2))))
+ if (is_poly_assign)
{
tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
use_vptr_copy || (lhs_attr.allocatable
--- /dev/null
+! { dg-do run }
+!
+! Test that pr78356 is fixed.
+! Contributed by Janus Weil and Andrew Benson
+
+program p
+ implicit none
+ type ac
+ end type
+ type, extends(ac) :: a
+ integer, allocatable :: b
+ end type
+ type n
+ class(ac), allocatable :: acr(:)
+ end type
+ type(n) :: s,t
+ allocate(a :: s%acr(1))
+ call nncp(s,t)
+ select type (cl => t%acr(1))
+ class is (a)
+ if (allocated(cl%b)) error stop
+ class default
+ error stop
+ end select
+contains
+ subroutine nncp(self,tg)
+ type(n) :: self, tg
+ allocate(tg%acr(1),source=self%acr(1))
+ end
+end
+