Dear All, The attached patch allows the original testcase to compile but attempting to use it runs into segfaults at runtime. The initializer for 'decay_t' has a bad FIELD_DECL for 'decay_gen_t' since it lacks the DECL_SIZE(_UNIT) fields but the TYPE_SIZE(_UNIT) fields are OK. The patch runs through the constructor and restores the missing fields, thus preventing the ICE in varasm.c.
Taking the reduced testcase of comment #4 and adding a main program: module decays implicit none interface real elemental function iface (arg) real, intent(in) :: arg end function end interface type :: decay_term_t type(decay_t), pointer :: unstable_product end type type :: decay_gen_t procedure(iface), nopass, pointer :: obs1_int type(decay_term_t), allocatable :: term end type type :: rng_t integer :: i end type type, extends (decay_gen_t) :: decay_t class(rng_t), allocatable :: rng end type class(decay_t), allocatable :: object end use decays type(decay_t), pointer :: template allocate (template) allocate (template%rng) template%obs1_int => cos print *, template%obs1_int (3.14159/2.) allocate (object, source = template) ! print *, object%obs1_int (3.14159/2.) ! This should be OK but it segfaults at runtime. object%obs1_int => sin print *, object%obs1_int (3.14159/2.) end This runs correctly. However, the commented out line causes a segfault in runtime. I haven't attempted yet to understand why this should be the case but it is obvious that the _copy procedure for decay_t has something wrong with it. The patch, therefore is neither ready in principle to be committed and uncouvers other nasties. I have two questions that I hope that somebody can answer: (i) How or why is it possible for build_constructor to produce incomplete FIELD_DECLS?; and (ii) What is wrong with the _copy procedure? I cannot return to the fray for slightly more than a week. Best regards Paul
Index: gcc/fortran/trans-expr.c =================================================================== *** gcc/fortran/trans-expr.c (revision 208048) --- gcc/fortran/trans-expr.c (working copy) *************** gfc_conv_structure (gfc_se * se, gfc_exp *** 6175,6180 **** --- 6175,6201 ---- se->expr = build_constructor (type, v); if (init) TREE_CONSTANT (se->expr) = 1; + + /* Verify that the DECL_SIZE fields have been set so that the + constructor is ready for varasm.c(output_constructor_regular_field). + TODO: Find out why this is very occasionally necessary. + See PR59198. */ + type = TREE_TYPE (se->expr); + if (TREE_CODE (type) == RECORD_TYPE) + { + tmp = TYPE_FIELDS (type); + while (tmp) + { + if (TREE_CODE (tmp) == FIELD_DECL + && DECL_SIZE_UNIT (tmp) == NULL_TREE) + { + DECL_SIZE (tmp) = TYPE_SIZE (TREE_TYPE (tmp)); + DECL_SIZE_UNIT (tmp) = TYPE_SIZE_UNIT (TREE_TYPE (tmp)); + } + tmp = TREE_CHAIN (tmp); + } + } + }