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);
+       }
+     }
+ 
  }
  
  

Reply via email to