Bug 41479 - [4.3/4.4/4.5 Regression] intent(out) for types with default initialization
[4.3/4.4/4.5 Regression] intent(out) for types with default initialization
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.5.0
: P4 normal
: 4.3.5
Assigned To: Not yet assigned to anyone
: wrong-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2009-09-26 21:12 UTC by Juergen Reuter
Modified: 2009-10-05 09:20 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-09-27 17:03:28


Attachments
test case for the mis-initialization (715 bytes, application/octet-stream)
2009-09-26 21:14 UTC, Juergen Reuter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Juergen Reuter 2009-09-26 21:12:47 UTC
The example below shows that besides the fact that declared as INTENT(OUT) the component 'n' is not initialized per default the second time. This is demanded by the FORTRAN standard. 
Example code:
program main

 type :: container_t
    integer :: n = 0
    ! if the following line is omitted, the problem disappears
    integer, dimension(:), allocatable :: a
 end type container_t

 type(container_t) :: container

 call init (container)
 print *, "Initial state:"
 call dump (container)

 container%n = 1
 print *, "Modified state:"
 call dump (container)

 call init (container)
 print *, "Initial state again:"
 call dump (container)

contains

 subroutine init (container)
   type(container_t), intent(out) :: container
 end subroutine init

 subroutine dump (container)
   type(container_t), intent(in) :: container
   print "(A,I0,1x,L)", "   value = ", container%n
 end subroutine dump

end program main
Comment 1 Juergen Reuter 2009-09-26 21:14:41 UTC
Created attachment 18661 [details]
test case for the mis-initialization
Comment 2 Jerry DeLisle 2009-09-27 00:50:08 UTC
gfortran is not considered release critical and so is never given a blocker status.

Changing to normal.

Regarding the intent(out) issue.  I will defer to others.  
Comment 3 Jerry DeLisle 2009-09-27 01:13:55 UTC
The problem goes away if the allocatable specification is removed from the declaration of 'a'

Problem also occurs on gfortran 4.3.0
Comment 4 Dominique d'Humieres 2009-09-27 10:04:04 UTC
> Regarding the intent(out) issue.  I will defer to others.

If the issue is valid, this a [4.3/4.4/4.5 Regression]. On *-apple-darwin9 GCC 4.2.4 gives:

[ibook-dhum] f90/bug% gfc42 pr41479.f90
[ibook-dhum] f90/bug% a.out 
 Initial state:
   value = 0
 Modified state:
   value = 1
 Initial state again:
   value = 0
Comment 5 Joost VandeVondele 2009-09-27 17:03:28 UTC
target independent bug.
Comment 6 kargl 2009-09-27 17:20:56 UTC
(In reply to comment #0)
> The example below shows that besides the fact that declared as INTENT(OUT) the
> component 'n' is not initialized per default the second time.

It's not initialized on the first call to INIT(), either.

Form -fdump-tree-original 


init (struct container_t & restrict container)
{
  if (container != 0)
    {
      if (container->a.data != 0B)
        {
          __builtin_free ((void *) container->a.data);
        }
      container->a.data = 0B;
    }
}

There is no assignment here.  If we look at MAIN

MAIN__ ()
{
  static struct container_t container = {.n=4242};
  static void init (struct container_t & restrict);
  static void dump (struct container_t & restrict);

  container.a.data = 0B;
  {
    struct container_t D.1317;
    struct container_t container_t.1;

    container_t.1.n = 4242;
    container_t.1.a.data = 0B;
    D.1317 = container;
    container = container_t.1;
    if (D.1317.a.data != 0B)
      {
        __builtin_free ((void *) D.1317.a.data);
      }
    D.1317.a.data = 0B;
  }
  init (&container);
  dump (&container);
  container.n = 1;
  dump (&container);
  init (&container);

we see the n = 4242 (I changed the value to 4242) from the
original declaration statement.

On a side note, if
  
   integer, dimension(:), allocatable :: a

is replaced with

   integer, dimension(:), pointer :: a

we get

REMOVE:kargl[272] ./z
   value = 4242
   value = 1
   value = 4242

and -fdump-tree-original shows

init (struct container_t & restrict container)
{
  if (container != 0)
    {
      {
        struct container_t D.1311;
        struct container_t container_t.1;

        container_t.1.n = 4242;
        D.1311 = container_t.1;
        *container = D.1311;
      }
    }
}

I suspect that this has been broken since allocatable component
were introduced into gfortran.


Comment 7 kargl 2009-09-27 18:18:54 UTC
Checking the 4.2 branch and trans-expr.c in trunk, it appears that
this chunk of code in gfc_conv_function_call() has gone missing.

2148 /* If an INTENT(OUT) dummy of derived type has a default
2149    initializer, it must be (re)initialized here. */
2150 if (fsym->attr.intent == INTENT_OUT
2151     && fsym->ts.type == BT_DERIVED
2152     && fsym->value)
2153   {
2154     gcc_assert (!fsym->attr.allocatable);
2155     tmp = gfc_trans_assignment (e, fsym->value, false);
2156     gfc_add_expr_to_block (&se->pre, tmp);
2157   }
Comment 8 Tobias Burnus 2009-10-02 09:54:23 UTC
(In reply to comment #7)
> Checking the 4.2 branch and trans-expr.c in trunk, it appears that
> this chunk of code in gfc_conv_function_call() has gone missing.

It was removed with the following patch:


Date: Tue Jul 24 19:16:36 2007
New Revision: 126885 / 126886

URL: http://gcc.gnu.org/viewcvs?view=revision&revision=126885
     http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126886
Log:
2007-07-24 Paul Thomas <pault@gcc.gnu.org>

        PR fortran/31205
        PR fortran/32842
        * trans-expr.c (gfc_conv_function_call): Remove the default
        initialization of intent(out) derived types.

From http://gcc.gnu.org/ml/gcc-patches/2007-06/msg02151.html:
  (ii) Remove the initialization of derived types with a default
  initializer from the caller to the callee.  The reasons for doing this
  are discussed in the PR (PR31205).  It has a gratifying effect on passing
  derived types with allocatable components, in that the amount of
  generated code goes down (see alloc_comp_basics_1.f90).

Thus I think that part is OK. (Doing the default initialization in the caller leads to wrong code if the caller does not know the interface of called procedure.) However, some callee initialization is now missing.
Comment 9 Tobias Burnus 2009-10-02 16:26:04 UTC
Subject: Bug 41479

Author: burnus
Date: Fri Oct  2 16:25:50 2009
New Revision: 152407

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152407
Log:
2009-10-02  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        * trans-decl.c (gfc_init_default_dt): Check for presence of
        the argument only if it is optional or in entry master.
        (init_intent_out_dt): Ditto; call gfc_init_default_dt
        for all derived types with initializers.

2009-10-02  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        * gfortran.dg/intent_out_5.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/intent_out_5.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog

Comment 10 Tobias Burnus 2009-10-05 09:19:27 UTC
Subject: Bug 41479

Author: burnus
Date: Mon Oct  5 09:19:13 2009
New Revision: 152444

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152444
Log:
2009-10-05  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        (init_intent_out_dt): Call gfc_init_default_dt
        for all derived types with initializers.

2009-10-05  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        * gfortran.dg/intent_out_5.f90: New test.


Added:
    branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/intent_out_5.f90
Modified:
    branches/gcc-4_4-branch/gcc/fortran/ChangeLog
    branches/gcc-4_4-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 11 Tobias Burnus 2009-10-05 09:20:03 UTC
Subject: Bug 41479

Author: burnus
Date: Mon Oct  5 09:19:52 2009
New Revision: 152445

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152445
Log:
2009-10-05  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        (init_intent_out_dt): Call gfc_init_default_dt
        for all derived types with initializers.

2009-10-05  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41479
        * gfortran.dg/intent_out_5.f90: New test.


Added:
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/intent_out_5.f90
Modified:
    branches/gcc-4_3-branch/gcc/fortran/ChangeLog
    branches/gcc-4_3-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog

Comment 12 Tobias Burnus 2009-10-05 09:20:29 UTC
FIXED on the trunk (4.5) and on the 4.3 and 4.4 branches.

Thanks for the report!