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 {