Re: [Patch, Fortran, 66035, v1] [5/6 Regression] gfortran ICE segfault

2015-05-11 Thread Andre Vehreschild
Hi Mikael,

  diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
  index cf607d0..402d9b9 100644
  --- a/gcc/fortran/trans-expr.c
  +++ b/gcc/fortran/trans-expr.c
  @@ -6881,6 +6881,30 @@ alloc_scalar_allocatable_for_subcomponent_assignment
  (stmtblock_t *block, TREE_TYPE (tmp), tmp,
 fold_convert (TREE_TYPE (tmp),
  size)); }
  +  else if (cm-ts.type == BT_CLASS)
  +{
  +  gcc_assert (expr2-ts.type == BT_CLASS || expr2-ts.type ==
  BT_DERIVED);
  +  if (expr2-ts.type == BT_DERIVED)
  +   {
  + tmp = gfc_get_symbol_decl (gfc_find_vtab (expr2-ts));
  + tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  + size = fold_convert (size_type_node, gfc_vptr_size_get (tmp));
  +   }
 Use TYPE_SIZE_UNIT of the rhs in this case, in the same way as in the
 else branch further below.

Er, but when I get TYPE_SIZE_UNIT () correctly, then it will grab the size
needed to store the %_vptr%size component. Do you really intent that? I need to
alloc the size of the polymorphic type of expr2 here.

snipp

  @@ -7008,7 +7032,9 @@ gfc_trans_subcomponent_assign (tree dest,
  gfc_component * cm, gfc_expr * expr, gfc_add_expr_to_block (block, tmp);
   }
 else if (init  (cm-attr.allocatable
  -  || (cm-ts.type == BT_CLASS  CLASS_DATA
  (cm)-attr.allocatable)))
  +  || (cm-ts.type == BT_CLASS  CLASS_DATA (cm)-attr.allocatable
  +   (expr-ts.type != BT_CLASS
  +  || CLASS_DATA (expr)-attr.allocatable
 maybe: || !CLASS_DATA (expr)-attr.allocatable
 (with a '!')?

No, I only want to copy the rhs to new memory, when it is allocatable. For all
other cases, one should not do this, to prevent a memory leak. Furthermore, is
the data copied to freshly allocated memory anyway. Have a look at the pseudo
code generated for the testcase in the patch.

Regards,
Andre
-- 
Andre Vehreschild * Email: vehre ad gmx dot de 


Re: [Patch, Fortran, 66035, v1] [5/6 Regression] gfortran ICE segfault

2015-05-10 Thread Mikael Morin
Le 08/05/2015 15:29, Andre Vehreschild a écrit :
 Hi all,
 
 please find attached a patch for 66035. An ICE occurred when in a structure
 constructor an allocatable component of type class was initialized with an
 existing class object. This was caused by 
 
 - the size of the memory to allocate for the component was miscalculated,
 - the vptr was not set correctly, and
 - when the class object to be used for init was allocatable already, it was
   copied wasting some memory instead of a view_convert inserted.
 
 All of the above are fixed by the attached patch.
 
 Bootstraps and regtests ok on x86_64-linux-gnu/f21 for trunk and gcc-5-trunk.
 
 Ok for trunk and gcc-5-trunk?
 
 Regards,
   Andre
 
 
 pr66035_1.patch
 
 diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
 index cf607d0..402d9b9 100644
 --- a/gcc/fortran/trans-expr.c
 +++ b/gcc/fortran/trans-expr.c
 @@ -6881,6 +6881,30 @@ alloc_scalar_allocatable_for_subcomponent_assignment 
 (stmtblock_t *block,
  TREE_TYPE (tmp), tmp,
  fold_convert (TREE_TYPE (tmp), size));
  }
 +  else if (cm-ts.type == BT_CLASS)
 +{
 +  gcc_assert (expr2-ts.type == BT_CLASS || expr2-ts.type == 
 BT_DERIVED);
 +  if (expr2-ts.type == BT_DERIVED)
 + {
 +   tmp = gfc_get_symbol_decl (gfc_find_vtab (expr2-ts));
 +   tmp = gfc_build_addr_expr (NULL_TREE, tmp);
 +   size = fold_convert (size_type_node, gfc_vptr_size_get (tmp));
 + }
Use TYPE_SIZE_UNIT of the rhs in this case, in the same way as in the
else branch further below.

 +  else
 + {
 +   gfc_expr *e2vtab;
 +   gfc_se se;
 +   e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
 +   gfc_add_vptr_component (e2vtab);
 +   gfc_add_size_component (e2vtab);
 +   gfc_init_se (se, NULL);
 +   gfc_conv_expr (se, e2vtab);
 +   gfc_add_block_to_block (block, se.pre);
 +   size = fold_convert (size_type_node, se.expr);
 +   gfc_free_expr (e2vtab);
 + }
 +  size_in_bytes = size;
 +}
else
  {
/* Otherwise use the length in bytes of the rhs.  */
 @@ -7008,7 +7032,9 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component 
 * cm, gfc_expr * expr,
gfc_add_expr_to_block (block, tmp);
  }
else if (init  (cm-attr.allocatable
 -|| (cm-ts.type == BT_CLASS  CLASS_DATA (cm)-attr.allocatable)))
 +|| (cm-ts.type == BT_CLASS  CLASS_DATA (cm)-attr.allocatable
 + (expr-ts.type != BT_CLASS
 +|| CLASS_DATA (expr)-attr.allocatable
maybe: || !CLASS_DATA (expr)-attr.allocatable
(with a '!')?

Mikael


[Patch, Fortran, 66035, v1] [5/6 Regression] gfortran ICE segfault

2015-05-08 Thread Andre Vehreschild
Hi all,

please find attached a patch for 66035. An ICE occurred when in a structure
constructor an allocatable component of type class was initialized with an
existing class object. This was caused by 

- the size of the memory to allocate for the component was miscalculated,
- the vptr was not set correctly, and
- when the class object to be used for init was allocatable already, it was
  copied wasting some memory instead of a view_convert inserted.

All of the above are fixed by the attached patch.

Bootstraps and regtests ok on x86_64-linux-gnu/f21 for trunk and gcc-5-trunk.

Ok for trunk and gcc-5-trunk?

Regards,
Andre
-- 
Andre Vehreschild * Email: vehre ad gmx dot de 


pr66035_1.clog
Description: Binary data
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index cf607d0..402d9b9 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6881,6 +6881,30 @@ alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
    TREE_TYPE (tmp), tmp,
    fold_convert (TREE_TYPE (tmp), size));
 }
+  else if (cm-ts.type == BT_CLASS)
+{
+  gcc_assert (expr2-ts.type == BT_CLASS || expr2-ts.type == BT_DERIVED);
+  if (expr2-ts.type == BT_DERIVED)
+	{
+	  tmp = gfc_get_symbol_decl (gfc_find_vtab (expr2-ts));
+	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+	  size = fold_convert (size_type_node, gfc_vptr_size_get (tmp));
+	}
+  else
+	{
+	  gfc_expr *e2vtab;
+	  gfc_se se;
+	  e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
+	  gfc_add_vptr_component (e2vtab);
+	  gfc_add_size_component (e2vtab);
+	  gfc_init_se (se, NULL);
+	  gfc_conv_expr (se, e2vtab);
+	  gfc_add_block_to_block (block, se.pre);
+	  size = fold_convert (size_type_node, se.expr);
+	  gfc_free_expr (e2vtab);
+	}
+  size_in_bytes = size;
+}
   else
 {
   /* Otherwise use the length in bytes of the rhs.  */
@@ -7008,7 +7032,9 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
   gfc_add_expr_to_block (block, tmp);
 }
   else if (init  (cm-attr.allocatable
-	   || (cm-ts.type == BT_CLASS  CLASS_DATA (cm)-attr.allocatable)))
+	   || (cm-ts.type == BT_CLASS  CLASS_DATA (cm)-attr.allocatable
+	(expr-ts.type != BT_CLASS
+		   || CLASS_DATA (expr)-attr.allocatable
 {
   /* Take care about non-array allocatable components here.  The alloc_*
 	 routine below is motivated by the alloc_scalar_allocatable_for_
@@ -7052,6 +7078,14 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
 	  tmp = gfc_build_memcpy_call (tmp, se.expr, size);
 	  gfc_add_expr_to_block (block, tmp);
 	}
+  else if (cm-ts.type == BT_CLASS  expr-ts.type == BT_CLASS)
+	{
+	  tmp = gfc_copy_class_to_class (se.expr, dest, integer_one_node,
+   CLASS_DATA (cm)-attr.unlimited_polymorphic);
+	  gfc_add_expr_to_block (block, tmp);
+	  gfc_add_modify (block, gfc_class_vptr_get (dest),
+			  gfc_class_vptr_get (se.expr));
+	}
   else
 	gfc_add_modify (block, tmp,
 			fold_convert (TREE_TYPE (tmp), se.expr));
diff --git a/gcc/testsuite/gfortran.dg/structure_constructor_13.f03 b/gcc/testsuite/gfortran.dg/structure_constructor_13.f03
new file mode 100644
index 000..c74e325
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/structure_constructor_13.f03
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! Contributed by Melven Roehrig-Zoellner  melven.roehrig-zoell...@dlr.de
+! PR fortran/66035
+
+program test_pr66035
+  type t
+  end type t
+  type w
+class(t), allocatable :: c
+  end type w
+
+  type(t) :: o
+
+  call test(o)
+contains
+  subroutine test(o)
+class(t), intent(inout) :: o
+type(w), dimension(:), allocatable :: list
+
+select type (o)
+  class is (t)
+list = [w(o)] ! This caused an ICE
+  class default
+call abort()
+end select
+  end subroutine
+end program