https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61950

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
          Component|middle-end                  |fortran

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we have (reduced from class_19.f03)

  <bb 6>:
  __builtin_memcpy (_10, &__def_init_foo_mod_Foo_outer, 0);
  _22 = MEM[(struct foo_outer *)_10].int._data;
  if (_22 != 0B)
    goto <bb 7>;
  else
    goto <bb 8>;

  <bb 7>:
  _gfortran_abort ();

from

      (struct __vtype_foo_mod_Foo_outer *) try3._vptr =
&__vtab_foo_mod_Foo_outer;
      (void) __builtin_memcpy ((void *) try3._data, (void *)
try3._vptr->_def_init, (unsigned long) try3._vptr->_size);
      if (try3._data->int._data != 0B)
        {
          _gfortran_abort ();
        }

see how the size argument to memcpy is zero!  FRE does that:

Value numbering _17 stmt = _17 = try3._vptr;
Setting value number of _17 to &__vtab_foo_mod_Foo_outer (changed)
Value numbering _18 stmt = _18 = _17->_size;
RHS _17->_size simplified to 0 has constants 1

fold_ctor_reference (type=0xfffb5930738, ctor=0xfffb5908e20, offset=32, size=
    32, from_decl=0xfffb5ab9fb0) at ../../trunk/gcc/gimple-fold.c:3059
3059      if (useless_type_conversion_p (type, TREE_TYPE (ctor))
(gdb) p debug_generic_expr (ctor)
{._hash=13054828, ._size=16, ._extends=0B,
._def_init=&__def_init_foo_mod_Foo_outer, ._copy=__copy_foo_mod_Foo_outer,
._final=__final_foo_mod_Foo_outer}
$241 = void

where we recurse through fold_nonarray_ctor_reference to

fold_ctor_reference (type=0xfffb5930738, ctor=0xfffb5900eb8, offset=0, size=
    32, from_decl=0xfffb5ab9fb0) at ../../trunk/gcc/gimple-fold.c:3059
3059      if (useless_type_conversion_p (type, TREE_TYPE (ctor))
(gdb) p debug_generic_expr (ctor)
16

but despite _size being 32bit in size:

    idx <field_decl 0xfffb59d89c0 _size
        type <integer_type 0xfffb5930738 integer(kind=4) public SI size
<integer_cst 0xfffb5901098 32> unit size <integer_cst 0xfffb59010b0 4>

the actual value in the initializer is of sizetype:

(gdb) p debug_tree (ctor)
 <integer_cst 0xfffb5900eb8 type <integer_type 0xfffb5930150 sizetype> constant
16>

so there is a mismatch created by the frontend here.

Frontend bug fixed by

Index: fortran/trans-expr.c
===================================================================
--- fortran/trans-expr.c        (revision 213342)
+++ fortran/trans-expr.c        (working copy)
@@ -6260,7 +6260,9 @@ gfc_conv_structure (gfc_se * se, gfc_exp
       else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
        {
          val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
-         CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
+         CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
+                                 fold_convert (TREE_TYPE (cm->backend_decl),
+                                               val));
        }
       else
        {

Reply via email to