From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12777 invoked by alias); 5 May 2010 14:13:45 -0000 Received: (qmail 12351 invoked by uid 48); 5 May 2010 14:12:55 -0000 Date: Wed, 05 May 2010 14:13:00 -0000 Message-ID: <20100505141255.12347.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug fortran/43990] [OOP] ICE in output_constructor_regular_field, at varasm.c:4995 In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "burnus at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-05/txt/msg00435.txt.bz2 ------- 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 , 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