The following program fails because the function result in "f" is never initialized. It should be default initialized, which works using other compilers. type A integer, pointer:: p => null () integer:: i=3 end type A type(A):: x x=f() if (associated(x%p) .or. x%i /= 3) call abort () contains function f() result (fr) type(A):: fr end function f end
See thread at http://gcc.gnu.org/ml/fortran/2010-09/msg00044.html (+ previous/later emails) for the discussion. Note: The following simple patch does *not* work but gives an ICE: test.f90:9:0: internal compiler error: in gfc_get_symbol_decl, at fortran/trans-decl.c:1055 --- resolve.c (Revision 163740) +++ resolve.c @@ -12175,27 +12147,33 @@ resolve_symbol (gfc_symbol *sym) || sym->ns->proc_name->attr.flavor != FL_MODULE))) gfc_error ("Threadprivate at %L isn't SAVEd", &sym->declared_at); /* If we have come this far we can apply default-initializers, as described in 14.7.5, to those variables that have not already - been assigned one. */ + been assigned one. That includes arrays with non-constant bounds + and function results. */ if (sym->ts.type == BT_DERIVED - && sym->attr.referenced && sym->ns == gfc_current_ns && !sym->value && !sym->attr.allocatable && !sym->attr.alloc_comp) { symbol_attribute *a = &sym->attr; if ((!a->save && !a->dummy && !a->pointer && !a->in_common && !a->use_assoc + && (sym->attr.referenced || sym->attr.result) && !(a->function && sym != sym->result)) || (a->dummy && a->intent == INTENT_OUT && !a->pointer)) apply_default_init (sym); }
(In reply to comment #1) > Note: The following simple patch does *not* work but gives an ICE: > test.f90:9:0: internal compiler error: in gfc_get_symbol_decl, at > fortran/trans-decl.c:1055 It seems to work if one adds if (!a->referenced && sym->value) gfc_set_sym_referenced (sym); after apply_default_init (sym); in the inner if-block.
(In reply to comment #2) > It seems to work if one adds > if (!a->referenced && sym->value) > gfc_set_sym_referenced (sym); As gfortran does not use a static initializer via sym->value but an assignment, this check does not work. The following patch should work: ---------------------------------------- --- resolve.c (revision 163759) +++ resolve.c (working copy) @@ -9476,6 +9476,7 @@ apply_default_init (gfc_symbol *sym) return; build_init_assign (sym, init); + sym->attr.referenced = 1; } /* Build an initializer for a local integer, real, complex, logical, or @@ -12148,7 +12149,6 @@ resolve_symbol (gfc_symbol *sym) described in 14.7.5, to those variables that have not already been assigned one. */ if (sym->ts.type == BT_DERIVED - && sym->attr.referenced && sym->ns == gfc_current_ns && !sym->value && !sym->attr.allocatable @@ -12158,6 +12158,7 @@ resolve_symbol (gfc_symbol *sym) if ((!a->save && !a->dummy && !a->pointer && !a->in_common && !a->use_assoc + && (a->referenced || a->result) && !(a->function && sym != sym->result)) || (a->dummy && a->intent == INTENT_OUT && !a->pointer)) apply_default_init (sym); @@ -12166,10 +12167,7 @@ resolve_symbol (gfc_symbol *sym) if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns && sym->attr.dummy && sym->attr.intent == INTENT_OUT && !sym->attr.pointer && !sym->attr.allocatable) - { - apply_default_init (sym); - gfc_set_sym_referenced (sym); - } + apply_default_init (sym); /* If this symbol has a type-spec, check it. */ if (sym->attr.flavor == FL_VARIABLE || sym->attr.flavor == FL_PARAMETER Extended test case Note, I failed to create a failing dummy test case. Seemingly, "sym->value" is set for the dummies below; thus, only the "f" part of the test case is failing without the patch above. ------------------ program test_init implicit none integer, target :: tgt type A integer, pointer:: p => null () integer:: i=3 end type A type(A):: x, y(3) x=f() if (associated(x%p) .or. x%i /= 3) call abort () y(1)%p => tgt y%i = 99 call sub1(3,y) if (associated(y(1)%p) .or. any(y(:)%i /= 3)) call abort () y(1)%p => tgt y%i = 99 call sub2(y) if (associated(y(1)%p) .or. any(y(:)%i /= 3)) call abort () contains function f() result (fr) type(A):: fr end function f subroutine sub1(n,x) integer :: n type(A), intent(out) :: x(n:n+2) end subroutine sub1 subroutine sub2(x) type(A), intent(out) :: x(:) end subroutine sub2 end program test_init
Subject: Bug 45489 Author: burnus Date: Thu Sep 2 10:11:39 2010 New Revision: 163767 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163767 Log: 2010-09-02 Tobias Burnus <burnus@net-b.de> PR fortran/45489 * resolve.c (apply_default_init): Mark symbol as referenced, if it is initialized. (resolve_symbol): Change intialized check for BT_DERIVED such that also function results get initialized; remove now obsolete gfc_set_sym_referenced for BT_CLASS. 2010-09-02 Tobias Burnus <burnus@net-b.de> PR fortran/45489 * gfortran.dg/initialization_27.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/initialization_27.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 45489 Author: burnus Date: Sat Sep 4 19:25:36 2010 New Revision: 163865 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163865 Log: 2010-09-04 Tobias Burnus <burnus@net-b.de> PR fortran/45489 * resolve.c (apply_default_init): Mark symbol as referenced, if it is initialized. (resolve_symbol): Change intialized check for BT_DERIVED such that also function results get initialized. 2010-09-04 Tobias Burnus <burnus@net-b.de> PR fortran/45489 * gfortran.dg/initialization_27.f90: New. Added: branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/initialization_27.f90 Modified: branches/gcc-4_5-branch/gcc/fortran/ChangeLog branches/gcc-4_5-branch/gcc/fortran/resolve.c branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
FIXED.