https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79230
--- Comment #8 from janus at gcc dot gnu.org --- Another variant, which removes the naming collision (and dimension attribute) in the character components, in order to make things clearer: program main_ut implicit none type :: data_t character, allocatable :: c1 end type type :: t1_t character, allocatable :: c2 class(data_t), pointer :: width_data end type call evaluator contains subroutine evaluator type(data_t), target :: par_real type(t1_t) :: field field%width_data => par_real end subroutine end The dump of the 'evaluator' function looks like this: evaluator () { struct t1_t field; struct data_t par_real; try { field.c2 = 0B; par_real.c1 = 0B; field.width_data._vptr = (struct __vtype_main_ut_Data_t * {ref-all}) &__vtab_main_ut_Data_t; field.width_data._data = &par_real; } finally { if (par_real.c1 != 0B) { __builtin_free ((void *) par_real.c1); par_real.c1 = 0B; } if (field.c2 != 0B) { __builtin_free ((void *) field.c2); field.c2 = 0B; } if (field.width_data.c1 != 0B) { __builtin_free ((void *) field.width_data.c1); field.width_data.c1 = 0B; } } } What is wrong here is the very last part, I think: if (field.width_data.c1 != 0B) { __builtin_free ((void *) field.width_data.c1); field.width_data.c1 = 0B; } It seems that 'width_data' is missing a _data reference in all three cases. Also the 'if'-condition is missing a check for that '_data' component being non-null, I guess. Or maybe we should rather call the finalization wrapper for the type 'data_t', which is being built here anyway and would also take care of freeing up 'c1'.