Message ID | CAGkQGiLJH4w+8Ri3JjbsnCOgHs9a5HMjLUnMnjFroX-KV6PNFA@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | [fortran] PR98573 - Dynamic type lost on assignment | expand |
Hi Paul, > This is a relatively obvious patch. The chunk in trans-array.c is not part > of the fix for the PR but does suppress some of the bad dtype's that arise > from allocation of class objects. The part in trans-stmt.c provides vptrs > for all class allocations if the expression3 is available. > > Regtests on FC33/x86_64 OK. Thanks for the patch! Best regards Thomas
On 23.01.21 10:04, Paul Richard Thomas via Fortran wrote: > This is a relatively obvious patch. The chunk in trans-array.c is not part > of the fix for the PR but does suppress some of the bad dtype's that arise > from allocation of class objects. Do you have a testcase for it? Either behavioral (dg-do run) or based on the tree-dump + scan? I think it would be useful to ensure that, even if it is not part of the PR – and hence the testcase. (At least it does not look as if the testcase goes beyond the PR.) > The part in trans-stmt.c provides vptrs > for all class allocations if the expression3 is available. > > [...] > > /* Set the vptr only when no source= is set. When source= is set, then > the trans_assignment below will set the vptr. */ > - if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold)) > + if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold > + || code->expr3->ts.type == BT_CLASS)) First, the comment needs to be updated as the branch is also called in some cases for 'source='. Additionally, I wonder whether there is the any issue with this and code along the line of the following (here for scalars, but arrays might cause additional issues): type t end type t class(t), allocatable :: cx type(t), allocatable :: ty allocate(ty, source=cx) end Where 'source=' is polymorphic – but the allocated variable is not. Already without your patch, I see: ty = (struct t *) __builtin_malloc (MAX_EXPR <(unsigned long) cx._vptr->_size, 1>); which may allocate too much. vptr is not set (obviously) and __vtab_MAIN___T._copy (cx._data, ty); looks fine. Thus, with the current code, the main issue seems to be only overallocation. And doing with the code above ty = cx will currently ICE in gfc_allocate_using_malloc (called by trans_class_assignment). I do not quite see whether those are separate issues or whether they are made worse (or better?) by your patch. Tobias ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 4bd4db877bd..306c2de7be7 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -5540,7 +5540,13 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, gfc_se se; int n; - type = TREE_TYPE (descriptor); + if (expr->ts.type == BT_CLASS + && expr3_desc != NULL_TREE + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (expr3_desc))) + type = TREE_TYPE (expr3_desc); + else + type = TREE_TYPE (descriptor); + stride = gfc_index_one_node; offset = gfc_index_zero_node; diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 547468f7648..2bd7fdf0f1c 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -6908,7 +6908,8 @@ gfc_trans_allocate (gfc_code * code) /* Set the vptr only when no source= is set. When source= is set, then the trans_assignment below will set the vptr. */ - if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold)) + if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold + || code->expr3->ts.type == BT_CLASS)) { if (expr3_vptr != NULL_TREE) /* The vtab is already known, so just assign it. */