http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52102
--- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-02-03 13:21:43 UTC --- >From the dump: two.a._data.data = (void * restrict) __builtin_malloc (8); __builtin_memset (two.a._data.data, 0, 8); two.a._data.offset = -1; { struct t D.1891; D.1891 = (*(struct t[0:] * restrict) two.a._data.data)[two.a._data.offset + 2]; The "D.1891 = " line looks odd: One should get the address of "two.a._data" and not the value. Additionally, one gets the address of element "[-1]" which is invalid. Also the loop is odd: One iterates through the elements of the SOURCE-expr, but one always writes to the same dst (here: the temporary variable D.1893): while (1) { if (S.6 > 1) goto L.1; { struct t D.1893; D.1893 = (*(struct t[2] * restrict) atmp.1.data)[S.6]; __vtab_MAIN___T._copy (&D.1893, &D.1891); By contrast, for: class(t), allocatable :: two(:) allocate (two(2), source=[t(4), t(6)]) One has in the loop D.1892 = (*(struct t[2] * restrict) atmp.1.data)[S.6]; __vtab_MAIN___T._copy (&D.1892, (struct t *) D.1882 + (sizetype) (((S.6 + 1) + D.1883) * (integer(kind=8)) two._vptr->_size)); with struct t[0:] * restrict D.1882; D.1882 = (struct t[0:] * restrict) two._data.data;