Bug 45489 - Default initialization of derived-type function result missing
Summary: Default initialization of derived-type function result missing
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Tobias Burnus
URL:
Keywords: wrong-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2010-09-01 21:01 UTC by Tobias Burnus
Modified: 2010-09-04 19:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-09-02 07:31:51


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-09-01 21:01:09 UTC
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
Comment 1 Tobias Burnus 2010-09-01 21:05:58 UTC
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);
     }
Comment 2 Tobias Burnus 2010-09-01 21:19:46 UTC
(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.
Comment 3 Tobias Burnus 2010-09-02 07:31:51 UTC
(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
Comment 4 Tobias Burnus 2010-09-02 10:11:58 UTC
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

Comment 5 Tobias Burnus 2010-09-04 19:25:50 UTC
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

Comment 6 Tobias Burnus 2010-09-04 19:48:17 UTC
FIXED.