[Bug fortran/54917] [4.7/4.8 Regression] [OOP] TRANSFER on polymorphic variable causes ICE

janus at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Oct 14 12:01:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54917

--- Comment #10 from janus at gcc dot gnu.org 2012-10-14 12:01:39 UTC ---
(In reply to comment #9)
> -fdump-tree-original shows the following:
> 
> [...]
>   __builtin_memcpy ((void *) &transfer.0, (void *) &c, MAX_EXPR <MIN_EXPR
> <D.1883, D.1882>, 0>);
> [...]
> 
> Clearly, the "&c" here should be "&c._data".

Moreover, the size of the memcpy should be determined by "c._vptr->_size". Both
is done by the following patch:


Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c    (revision 192392)
+++ gcc/fortran/trans-intrinsic.c    (working copy)
@@ -5376,18 +5376,28 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr
   if (arg->expr->rank == 0)
     {
       gfc_conv_expr_reference (&argse, arg->expr);
-      source = argse.expr;
+      if (arg->expr->ts.type == BT_CLASS)
+    source = gfc_class_data_get (argse.expr);
+      else
+    source = argse.expr;

-      source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
-                            argse.expr));
-
       /* Obtain the source word length.  */
-      if (arg->expr->ts.type == BT_CHARACTER)
-    tmp = size_of_string_in_bytes (arg->expr->ts.kind,
-                       argse.string_length);
-      else
-    tmp = fold_convert (gfc_array_index_type,
-                size_in_bytes (source_type)); 
+      switch (arg->expr->ts.type)
+    {
+    case BT_CHARACTER:
+      tmp = size_of_string_in_bytes (arg->expr->ts.kind,
+                     argse.string_length);
+      break;
+    case BT_CLASS:
+      tmp = gfc_vtable_size_get (argse.expr);
+      break;
+    default:
+      source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
+                                source));
+      tmp = fold_convert (gfc_array_index_type,
+                  size_in_bytes (source_type));
+      break;
+    }
     }
   else
     {



More information about the Gcc-bugs mailing list