Hi! The bug here is that it dereferences expr->ts.u.cl if non-NULL unconditionally, no matter what expr->ts.type is. But, ts.u is an union, where ts.u.cl is only valid for BT_CHARACTER, ts.u.derived for BT_DERIVED etc. ts.u.pad (an int rather than pointer) for BT_HOLLERITH? and unused in others. So, as on the testcase, where expr->ts.type == BT_DERIVED, expr->ts.u.derived points to a gfc_symbol structure and thus dereferencing ts.u.cl means reading gfc_symbol bytes as if it is gfc_charlen. length_from_typespec is a bool, which can be only false or true, but on the testcase happens to point to a byte in gfc_symbol that has some other value (60 in my case), so the read is undefined behavior.
Fixed by doing it only when ts.u.cl is valid. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-08-17 Jakub Jelinek <ja...@redhat.com> PR fortran/67496 * trans-array.c (trans_array_constructor): Load expr->ts.u.cl->length_from_typespec only if expr->ts.type is BT_CHARACTER. * gfortran.dg/pr67496.f90: New test. --- gcc/fortran/trans-array.c.jj 2016-08-12 17:33:44.000000000 +0200 +++ gcc/fortran/trans-array.c 2016-08-17 15:20:44.248509114 +0200 @@ -2239,7 +2239,8 @@ trans_array_constructor (gfc_ss * ss, lo /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no typespec was given for the array constructor. */ - typespec_chararray_ctor = (expr->ts.u.cl + typespec_chararray_ctor = (expr->ts.type == BT_CHARACTER + && expr->ts.u.cl && expr->ts.u.cl->length_from_typespec); if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) --- gcc/testsuite/gfortran.dg/pr67496.f90.jj 2016-08-17 15:28:45.445223929 +0200 +++ gcc/testsuite/gfortran.dg/pr67496.f90 2016-08-17 15:28:09.000000000 +0200 @@ -0,0 +1,12 @@ +! PR fortran/67496 +! { dg-do compile } + + type :: a + end type a + type :: b + type (a) :: j(1) + end type b + type(a) :: x + type(b) :: y + y = b((/x/)) +end Jakub