Here's the fix and a test case for the regression PR 71047 introduced by the DEC STRUCTURE/UNION patch (commit 235999).
Turns out I was a bit greedy about adding component refs to structure constructors in gfc_default_initializer. Fixed to only add them to FL_STRUCTURE and FL_UNION symbols, which expect them during translation. The component ref was being added to constructors for the hidden _data and _vptr members of CLASS components, causing the code for their real initialization to be skipped by the middle-end. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71047 --- Fritz Reese
From f1ee9fb07728f69631f9795ba01b590d2277b6f3 Mon Sep 17 00:00:00 2001 From: Fritz O. Reese <fritzore...@gmail.com> Date: Thu, 12 May 2016 18:04:15 -0400 Subject: [PATCH] Remove extraneous component refs from derived type constructors. gcc/fortran/ PR fortran/71047 * expr.c (gfc_default_initializer): Avoid extra component refs in constructors for derived types and classes. gcc/testsuite/gfortran.dg/ PR fortran/71047 * pr71047.f08: New test. --- gcc/fortran/expr.c | 5 +++- gcc/testsuite/gfortran.dg/pr71047.f08 | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr71047.f08 diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 6ebe08b..816ef01 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3975,7 +3975,10 @@ gfc_default_initializer (gfc_typespec *ts) if (comp->initializer) { - ctor->n.component = comp; + // Save the component ref for STRUCTUREs and UNIONs. + if (ts->u.derived->attr.flavor == FL_STRUCT + || ts->u.derived->attr.flavor == FL_UNION) + ctor->n.component = comp; ctor->expr = gfc_copy_expr (comp->initializer); if ((comp->ts.type != comp->initializer->ts.type || comp->ts.kind != comp->initializer->ts.kind) diff --git a/gcc/testsuite/gfortran.dg/pr71047.f08 b/gcc/testsuite/gfortran.dg/pr71047.f08 new file mode 100644 index 0000000..61a0ad4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr71047.f08 @@ -0,0 +1,48 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! Fortran/PR71047 +! + +module m + implicit none + + type, abstract :: c_abstr + integer :: i = 0 + end type c_abstr + + type, extends(c_abstr) :: t_a + class(c_abstr), allocatable :: f + end type t_a + + type, extends(c_abstr) :: t_b + end type t_b + +contains + + subroutine set(y,x) + class(c_abstr), intent(in) :: x + type(t_a), intent(out) :: y + allocate( y%f , source=x ) + end subroutine set + +end module m + + +program p + use m + implicit none + + type(t_a) :: res + type(t_b) :: var + + call set( res , var ) + write(*,*) res%i + +end program p + +! +! Check to ensure the vtable is actually initialized. +! +! { dg-final { scan-tree-dump "t_a\\.\\d+\\.f\\._vptr =" "original" } } +! -- 1.7.1