------- Comment #2 from burnus at gcc dot gnu dot org 2010-05-05 14:12 ------- The problem seems to be the initialization at gfc_conv_structure (init = 1) in trans-expr.c:
We have: logical :: l = .true. class(t),pointer :: cp => null() and thus: (gdb) p expr->ts.u.derived->components->name $12 = 0x2aaaaab41ea8 "l" (gdb) p expr->ts.u.derived->components->next->name $13 = 0x2aaaaab41eb8 "cp" (gdb) p expr->ts.u.derived->components->next->ts.type $14 = BT_CLASS (gdb) p expr->ts.u.derived->components->next->attr.pointer $15 = 0 The later is simply not true: We have a pointer. if (cm->ts.type == BT_CLASS && !cm->attr.proc_pointer) { gfc_component *data; data = gfc_find_component (cm->ts.u.derived, "$data", true, true); Somehow this gives the wrong result in terms of the offset, i.e. one tries to initialize: t.l at position (&t + (0 byte)) and then one tries to initialize t.$data (!) at (&t + 0) but it should be (&t + 4) - or (&(t.class) + 0). The following patch fixes the problem, though I have the feeling it papers over some logic problem (cf. below): --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -4328,10 +4328,9 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init) c; c = gfc_constructor_next (c), cm = cm->next) { /* Skip absent members in default initializers and allocatable - components. Although the latter have a default initializer - of EXPR_NULL,... by default, the static nullify is not needed - since this is done every time we come into scope. */ - if (!c->expr || cm->attr.allocatable) + components, and NULL initialization of pointers, which are + automatically handled through zero initialization. */ + if (!c->expr || cm->attr.allocatable || c->expr->expr_type == EXPR_NULL) continue; if (cm->ts.type == BT_CLASS && !cm->attr.proc_pointer) (By the way, the comment above looked bogus: "since this is done every time we come in scope" is only true if the variable is STATIC just due to -fmax-stack-var-size. Otherwise, it will be ("only") zero initialized through "= {}".) * * * The "fix" above is likely to break if one uses <type>, pointer :: ptr => nonNULLtarget (allowed since Fortran 2008) where the RHS can be something different than EXPR_NULL. The problem seems to be that already the class struct is a pointer and not only its content, i.e. "t.class.$data = NULL" vs. "t.class == NULL". Or maybe only the reference goes wrong; cf. t.class.$data (OK) vs. t.$data (wrong). F2008 has: R442 component-initialization is = constant-expr or => null-init or => initial-data-target R443 initial-data-target is designator C461 (R443) The designator shall designate a nonallocatable variable that has the TARGET and SAVE attributes and does not have a vector subscript. Every subscript, section subscript, substring starting point, and substring ending point in designator shall be a constant expression." * * * Failing dump (for PROGRAM - not shown for MODULE): static struct t default_t = {.l=1, .$data=0B}; working with the patch above: static struct t default_t = {.l=1}; -- burnus at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |pault at gcc dot gnu dot org Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2010-05-05 14:12:54 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43990