Bug 34438 - gfortran not compliant w.r.t default initialization of derived type component and implicit SAVE attribute
Summary: gfortran not compliant w.r.t default initialization of derived type component...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.3
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords:
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2007-12-11 23:14 UTC by Sven Buijssen
Modified: 2007-12-28 10:54 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-12-14 12:53:12


Attachments
A prototype patch (1.29 KB, patch)
2007-12-15 00:29 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Buijssen 2007-12-11 23:14:15 UTC
gfortran 4.1.x, 4.2.x and 4.3.x are not compliant with the standard, section 4.4

'Unlike explicit initialization, default initialization does not imply that
the object has the SAVE attribute'

for the following testcase:


--- cut here ---
program main
  type myint
    integer :: bar = 0
  end type myint

  call recfunc(1)

contains

  recursive subroutine recfunc(ivalue)
    integer, intent(in) :: ivalue
    type(myint) :: foo

    foo%bar = ivalue
    if (ivalue .le. 3) then
      print *, "recursion level", ivalue, "value of local variable:", foo%bar
      call recfunc(ivalue + 1)
      print *, "recursion level", ivalue, "value of local variable:", foo%bar
    endif

  end subroutine recfunc

end program main
--- cut here ---

The default initialization of the component "bar" leads to "type(myint) ::
foo" having the SAVE attribute when compiled with gfortran. But "foo" should
only get the SAVE attribute if it were explicitly initialized. (The constraint
in 11.3 does not hold here)

$ gfortran -Wall demo.f90  && ./a.out
 recursion level           1 value of local variable:           1
 recursion level           2 value of local variable:           2
 recursion level           3 value of local variable:           3
 recursion level           3 value of local variable:           4
 recursion level           2 value of local variable:           4
 recursion level           1 value of local variable:           4

Recent version of PGI, Pathscale, Intel, SunStudio and G95 yield instead:
 recursion level 1 value of local variable: 1
 recursion level 2 value of local variable: 2
 recursion level 3 value of local variable: 3
 recursion level 3 value of local variable: 3
 recursion level 2 value of local variable: 2
 recursion level 1 value of local variable: 1

gfortran behaves like the other compilers when the default initialization of
component "bar" in the type definition is removed:

  [...]
  type myint
    integer :: bar
  end type myint
  [...]


Conversely, the compilers mentioned behave like gfortran if the variable "foo"
explicitly gets the SAVE attribute:

    [...]
    type(myint), save :: foo
    [...]


For sake of completeness:
$ gfortran -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1.x/configure --enable-shared --enable-languages=c,c++,fortran --enable-threads --enable-__cxa_atexit
Thread model: posix
gcc version 4.1.3 20071211 (prerelease)

$ gfortran -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.2.x/configure --enable-shared --enable-languages=c,c++,fortran --enable-threads --enable-__cxa_atexit
Thread model: posix
gcc version 4.2.3 20071211 (prerelease)

$ gfortran -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.3.x/configure --enable-shared --enable-languages=c,c++,fortran --enable-threads --enable-__cxa_atexit
Thread model: posix
gcc version 4.3.0 20071211 (experimental) (GCC)
Comment 1 kargls 2007-12-11 23:22:56 UTC
Can you provide a standard conforming program that 
illustrates the problem (because your code violates
the standard)?
Comment 2 Sven Buijssen 2007-12-12 15:04:08 UTC
Having reread the Fortran 95 language spec I don't see why the initial testcase violates the standard. But I managed to distill a testcase that does not need recursive functions and still triggers the bug of 'foo' getting implicitly the SAVE attribute:

--- cut here ---
module demo
  implicit none
  private
  type myint
    integer :: bar = 42
  end type myint
  public :: func
contains
  subroutine func(ivalue)
    integer, intent(in) :: ivalue
    type(myint) :: foo
    print *, foo%bar
    foo%bar = ivalue
  end subroutine func
end module demo

program main
  use demo
  implicit none
  call func(1)
  call func(2)
end program main
--- cut here ---

In case this piece of code still violates the standard, I would very much appreciate a hint where and why exactly it does. (Sorry to waste your time.)

gfortran 4.[1-2].x gives:
$ gfortran -W -Wall -pedantic -std=f95 demo3.f90 && ./a.out
          42
           1
while one would expect two times '42' as do Intel Fortran 9.x/10.x, PGI 7.x,
Pathscale 3.x, recent g95 versions, Compaq Fortran X5.4A-1684 and Sun Fortran 95 8.3 2007/07/18.

Without the private/public statements gfortran 4.3.x exhibits the same behaviour. The test case above, however, gives

    type(myint) :: foo
                     1
Error: Fortran 2003: PUBLIC variable 'foo' at (1) of PRIVATE derived type 'myint'

which seems unrelated to me and for which I probably should submit a new bug report. I added this information here nonetheless as it might help to trace the problem.
Comment 3 Joost VandeVondele 2007-12-12 16:11:57 UTC
(In reply to comment #2)

I had confirmed the bug already on the first testcase, which is fine. 


Comment 4 Tobias Burnus 2007-12-12 20:29:15 UTC
> Error: Fortran 2003: PUBLIC variable 'foo' at (1) of PRIVATE derived type
> 'myint'
> which seems unrelated to me and for which I probably should submit a new bug
> report.

It is unrelated, but simple to fix; patch: http://gcc.gnu.org/ml/fortran/2007-12/msg00153.html

(I think the first example is standard conform and should be enough, though I am glad that you created the other example and found a diagnostics bug.)

Thanks for your two-in-one bugreport.
Comment 5 Paul Thomas 2007-12-14 12:53:12 UTC
I can see a clean way to do this one - I shall be stuck in Frankfurt for three hours tonight; I'll do it then.

Paul
Comment 6 Tobias Burnus 2007-12-14 15:14:41 UTC
Subject: Bug 34438

Author: burnus
Date: Fri Dec 14 15:14:29 2007
New Revision: 130933

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130933
Log:
2007-12-14  Tobias Burnus  <burnus@net-b.de>

        PR fortran/34438
        * resolve.c (resolve_symbol): Do not emit public-variable-
        of-private-derived-type error for non-module variables.

2007-12-14  Tobias Burnus  <burnus@net-b.de>

        PR fortran/34438
        * gfortran.dg/private_type_10.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/private_type_10.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Paul Thomas 2007-12-15 00:29:17 UTC
Created attachment 14761 [details]
A prototype patch

This is as far as I got at the airport - it fixes the problem but has not yet been fully regtested.  'twill be done on Sunday.

Paul
Comment 8 Tobias Burnus 2007-12-17 20:03:39 UTC
Patch: http://gcc.gnu.org/ml/fortran/2007-12/msg00219.html
Comment 9 Paul Thomas 2007-12-21 21:20:52 UTC
Subject: Bug 34438

Author: pault
Date: Fri Dec 21 21:20:38 2007
New Revision: 131124

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131124
Log:
2007-12-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34438
	* trans-decl.c (gfc_finish_var_decl): Do not mark derived types
	with default initializers as TREE_STATIC unless they are in the
	main program scope.
	(gfc_get_symbol_decl): Pass derived types with a default
	initializer to gfc_defer_symbol_init.
	(init_default_dt): Apply default initializer to a derived type.
	(init_intent_out_dt): Call init_default_dt.
	(gfc_trans_deferred_vars): Ditto.

	* module.c (read_module): Check sym->module is there before
	using it in a string comparison.

2007-12-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34438
	* gfortran.dg/default_initialization_3.f90: New test.

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

Comment 10 Thomas Koenig 2007-12-26 14:25:03 UTC
This should be fixed on trunk.

Closing.
Comment 11 Sven Buijssen 2007-12-26 22:00:59 UTC
Can this patch be backported to 4.2?
Comment 12 kargls 2007-12-26 23:42:10 UTC
(In reply to comment #11)
> Can this patch be backported to 4.2?
> 

Is it a regression from an earlier version of gfortran?
If the answer to this question is 'No', then it is not
a candidate for a back port.
Comment 13 Sven Buijssen 2007-12-28 10:54:01 UTC
(In reply to comment #12)
No, it is not a regression. All releases since 4.0.0 and the 4.[0-2] branches are affected. I just asked because the only information I could find about the current backport policy is the thread http://gcc.gnu.org/ml/fortran/2006-10/msg00582.html.

My understanding of it, which might very well be wrong, is that bug 34438 - being one that produces wrong code - could meet the backport criteria such that we could see it fixed in an eventual 4.2.3.

Never mind, thank you guys very much for fixing it on the trunk.