diff mbox series

[fortran] PR98573 - Dynamic type lost on assignment

Message ID CAGkQGiLJH4w+8Ri3JjbsnCOgHs9a5HMjLUnMnjFroX-KV6PNFA@mail.gmail.com
State New
Headers show
Series [fortran] PR98573 - Dynamic type lost on assignment | expand

Commit Message

Paul Richard Thomas Jan. 23, 2021, 9:04 a.m. UTC
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

Paul

Fortran: Fix missing setting of vptrs in allocate statements [PR98573].

2021-01-22  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/98573
* trans-array.c (gfc_array_init_size): If expr3 descriptor is
present, use it for the type.
* trans-stmt.c (gfc_trans_allocate): Use the expr3 vptr for all
class allocations.

gcc/testsuite/
PR fortran/98573
* gfortran.dg/associated_target_7.f90 : New test.

Comments

Thomas Koenig Jan. 27, 2021, 12:18 p.m. UTC | #1
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
Tobias Burnus Jan. 29, 2021, 10:57 a.m. UTC | #2
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 mbox series

Patch

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.  */