https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64921
--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Uroš Bizjak from comment #18) > (In reply to Uroš Bizjak from comment #17) > > (In reply to Mat Cross from comment #14) > > > For the record, perhaps it is of interest for me to note that we are > > > running > > > into this (cf. PR64230 comment 9) on code like > > > > > > Program test > > > Implicit None > > > Type :: t1 > > > Integer, Allocatable :: i > > > End Type > > > Type :: t2 > > > Integer, Allocatable :: i > > > End Type > > > Type, Extends (t1) :: t3 > > > Type (t2) :: j > > > End Type > > > Type, Extends (t3) :: t4 > > > Integer, Allocatable :: k > > > End Type > > > Call s > > > Print *, 'ok' > > > Contains > > > Subroutine s > > > Class (t1), Allocatable :: x > > > Allocate (t4 :: x) > > > End Subroutine > > > End Program > > > > > > Since the crash is in bad compiler-generated finalization code (since > > > 4.9), > > > and given that (if I recall correctly) gfortran is using the Fortran 2008 > > > semantics for entities declared in a main program being implicitly saved, > > > this is why removing the Deallocate (in the comment 12 example) works - > > > the > > > finalizer is never called then. > > > > No wonder this test crashes. Tree-optimizers (-O2) on x86_64 produce: > > [...] > > I was able to trace dumps down to _.fre2 tree dump, where we have: > > <bb 12>: > # idx_104 = PHI <0(11), idx_122(16)> > offset_115 = 0; > ptr2_119 = (struct t3 *) offset_115; > _120 = &ptr2_119->j; This isn't a dereference, it's just an address computation. Iff j is not at offset zero then of course... if (_120 != 0B) goto <bb 19>; else goto <bb 22>; <bb 19>: _121 = ptr2_119->j.i; we'll crash right here. So the question is whether the frontend emits the correct test against zero: offset = offset * byte_stride; D.3466 = (void *) array->data; D.3467 = D.3466; D.3465 = 8; D.3469 = 8; __builtin_memcpy ((void *) &transfer.4, (void *) &D.3467, (unsigned long) MAX_EXPR <MIN_EXPR <D.3469, D.3465>, 0>); ptr2 = (struct t4 *) (transfer.4 + offset); if (ptr2 != 0B) { { integer(kind=4) stat.5; if (ptr2->k == 0B) to me it looks like if we really want to test transfer.4 (array->data) against zero. We do 0x0000000000400b26 <+502>: cmp $0xfffffffffffffff8,%r15 0x0000000000400b2a <+506>: je 0x400b42 <test+530> => 0x0000000000400b2c <+508>: mov 0x8(%r15),%rdi and %r15 is zero, so offset is _not_ zero here (but ends up constant propagated and we "optimize" the compare - offset seems to be 8). > This can't be right, we have a dereference from zero. If the frontend > produced correct code, then tree-optimization passes made a mess here. > > CC Richi.