Bug 34143 - alloc_comp_constructor.f90 fails with -fdefault-integer-8
Summary: alloc_comp_constructor.f90 fails with -fdefault-integer-8
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: accepts-invalid, ice-on-invalid-code
Depends on:
Blocks: default-integer-8
  Show dependency treegraph
 
Reported: 2007-11-18 20:02 UTC by Thomas Koenig
Modified: 2008-11-30 07:50 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-02-05 13:05:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2007-11-18 20:02:50 UTC
Reduced from a failure of alloc_comp_constructor.f90
with -fdefault-integer-8 on i686-pc-linux-gnu:

$ cat alloc_1.f90 
Program test_constructor

    implicit none

    type :: thytype
        integer(4) :: a(2,2)
    end type thytype

    type :: mytype
        integer(4), allocatable :: a(:, :)
        type(thytype), allocatable :: q(:)
    end type mytype

    type (mytype) :: x
    integer, allocatable :: yy(:,:)
    type (thytype), allocatable :: bar(:)

    ! Check that unallocated allocatables work
    x = mytype(yy, bar)
    if (allocated(x%a) .or. allocated(x%q)) call abort()

end program test_constructor
$ gfortran alloc_1.f90 
$ ./a.out
$ gfortran -fdefault-integer-8 alloc_1.f90 
$ ./a.out
Fortran runtime error: Attempt to allocate a negative amount of memory.
Comment 1 Jerry DeLisle 2007-11-18 21:48:23 UTC
The test case given here passes for me on x86-64 with both -m32 and -m64 and with or without -fdefault-integer-8. hmm!
Comment 2 Thomas Koenig 2007-11-18 22:04:27 UTC
(In reply to comment #1)
> The test case given here passes for me on x86-64 with both -m32 and -m64 and
> with or without -fdefault-integer-8. hmm!

Does the original test case pass?
Comment 3 Jerry DeLisle 2007-11-18 23:41:16 UTC
OK, the original test case fails as reported.  Replacing aborts with printin the line number that fails:

 fail 39
 fail 40
 fail 80
 fail 81
Comment 4 Francois-Xavier Coudert 2007-11-20 13:03:36 UTC
The Intel and Sun compilers complain that this code is not legal, because you can't do "x = mytype(yy, bar)" if yy is not allocated.

Otherwise, a reduced testcase on x86_64-linux is:

  type t
    integer, allocatable :: a(:)
  end type t

  type(t) :: x
  integer(kind=8), allocatable :: yy(:)

  x = t(yy)
  if (allocated(x%a)) print *, "bug"
end
Comment 5 Francois-Xavier Coudert 2007-11-22 08:56:35 UTC
Erik, Paul, as authors of the original patch and testcases, can you confirm my conclusion that the code in comment #4 (and thus, the gfortran.dg/alloc_comp_constructor_1.f90 testcase) is not legal, for the reason I indicate in the comment?
Comment 6 Tobias Burnus 2007-11-22 13:18:39 UTC
(In reply to comment #4)
> The Intel and Sun compilers complain that this code is not legal, because you
> can't do "x = mytype(yy, bar)" if yy is not allocated.

I cannot reproduce this with the Sun Compiler, only with ifort. Besides, following the Fortran 2003 standard, I believe the program is valid.

"If a component of a derived type is allocatable, the corresponding constructor expression shall either be a reference to the intrinsic function NULL with no arguments, an allocatable entity of the same rank, or shall evaluate to an entity of the same rank. If the expression is a reference to the intrinsic function NULL, the corresponding component of the constructor has a status of unallocated. If the expression is an allocatable entity, the corresponding component of the constructor has the same allocation status as that allocatable entity and, if it is allocated, the same dynamic type, bounds, and value;"

(Fortran 2003 standard, "4.5.9 Construction of derived-type values")
Comment 7 Paul Thomas 2007-11-30 07:49:12 UTC
(In reply to comment #5)
> Erik, Paul, as authors of the original patch and testcases, can you confirm my
> conclusion that the code in comment #4 (and thus, the
> gfortran.dg/alloc_comp_constructor_1.f90 testcase) is not legal, for the reason
> I indicate in the comment?
> 
Sorry - I missed this discussion compeletly.

Tobias' analysis is correct. It is legal.  In functional terms, the descriptor with its null pointer is passed to the descriptor field of the derived type.

Cheers

Paul
Comment 8 Paul Thomas 2008-02-05 12:57:25 UTC
I just noticed that this is due to incorrect or non-existent type/kind checking in the constructor 'mytype'.  With -fdefault-integer-8, yy has KIND=8, whereas the corresponding component has KIND=4, as given by the declaration. The runtime segfault is an obvious outcome.

Is the correct thing to throw an error or to quietly do the conversion?

Paul
Comment 9 Paul Thomas 2008-02-05 13:05:08 UTC
I've knocked back it's priority but have assigned it to myself to compensate.

Paul
Comment 10 Paul Thomas 2008-02-06 08:33:56 UTC
This bug is caused by gfc_conv_intrinsic_conversion calling gfc_conv_intrinsic_function_args, which builds a temporary without checking if the allocatable array 'yy' has been allocated or not.

This can be cured by looking for a null data field of the argument and converting that directly. Alternatively, the dimension 0 lbound and ubound being set to the same value on scope entry would accomplish the same result.  I'll see which looks the most economic.

Cheers

Paul  
Comment 11 Tobias Burnus 2008-02-06 09:09:59 UTC
> Is the correct thing to throw an error or to quietly do the conversion?
I tried the example (with integer(4) and integer(8)) with several compilers and none of them gave an error. (With -Wall g95 gives a conversion warning).

I thus think it is valid and one should do the conversion silently (except for -Wconversion).

From the Fortran 2003 standard:

"For a nonpointer component, the declared type and type parameters of the component and expr shall conform in the same way as for a variable and expr in an intrinsic assignment statement (7.4.1.2), as specified in Table 7.8."
Comment 12 Paul Thomas 2008-02-11 17:48:11 UTC
(In reply to comment #11)

OK I have a fix, up to a wrinkle that raises a standard question:

alloc_comp_constructor.f90 now compiles and runs OK but aborts because the bounds are changed by the implicit conversion when -fdefault-integer-8 is used.

All that the standard says, as far as I can tell is that the descriptor be copied.  In fact, Erik and I had temporaries renormalised to unity lbounds; I am begining to think that this is incorrect.  If so, the bounds checks in the testcase will fail, as they are doing with the implicit conversion.

Cheers

Paul

Comment 13 Dominique d'Humieres 2008-02-12 10:54:17 UTC
The problem of conversion shows up even without -fdefault-integer-8 along with bound problems as shown by the following code:

integer, parameter :: ik=4
type :: struct
   integer(4), allocatable :: ib(:)
end type struct
integer, parameter :: from=-1, to=2
integer(ik), allocatable :: ia(:)
type(struct) :: x
allocate(ia(from:to))
print *, 'bounds, full array           ', lbound(ia), ubound(ia)
print *, 'bounds, full implicit section', lbound(ia(:)), ubound(ia(:))
print *, 'bounds, full explicit section', lbound(ia(from:to)), ubound(ia(from:to))
print *, 'derived type, ik=', ik
x=struct(ia)
print *, 'bounds, full array           ', lbound(x%ib), ubound(x%ib)
x=struct(ia(:))
print *, 'bounds, full implicit section', lbound(x%ib), ubound(x%ib)
x=struct(ia(from:to))
print *, 'bounds, full explicit section', lbound(x%ib), ubound(x%ib)
deallocate(ia)
end

with ik = 4, the ouput is:

 bounds, full array                     -1           2
 bounds, full implicit section           1           4
 bounds, full explicit section           1           4
 derived type, ik=           4
 bounds, full array                     -1           2
 bounds, full implicit section          -1           2    <-- should not it be 1 4 as above?
 bounds, full explicit section           1           4

with ik = 8:

...
 derived type, ik=           8
 bounds, full array                      1           4    <--- should not it be -1 2 as for ik = 4?
 bounds, full implicit section           1           4
 bounds, full explicit section           1           4

Comment 14 Paul Thomas 2008-11-24 06:35:53 UTC
Subject: Bug 34143

Author: pault
Date: Mon Nov 24 06:34:16 2008
New Revision: 142148

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142148
Log:
2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34820
	* trans-expr.c (gfc_conv_function_call): Remove all code to
	deallocate intent out derived types with allocatable
	components.
	(gfc_trans_assignment_1): An assignment from a scalar to an
	array of derived types with allocatable components, requires
	a deep copy to each array element and deallocation of the
	converted rhs expression afterwards.
	* trans-array.c : Minor whitespace.
	* trans-decl.c (init_intent_out_dt): Add code to deallocate
	allocatable components of derived types with intent out.
	(generate_local_decl): If these types are unused, set them
	referenced anyway but allow the uninitialized warning.

	PR fortran/34143
	* trans-expr.c (gfc_trans_subcomponent_assign): If a conversion
	expression has a null data pointer argument, nullify the
	allocatable component.

	PR fortran/32795
	* trans-expr.c (gfc_trans_subcomponent_assign): Only nullify
	the data pointer if the source is not a variable.

2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34820
	* gfortran.dg/alloc_comp_constructor_6.f90 : New test.
	* gfortran.dg/alloc_comp_basics_1.f90 : Reduce expected refs to
	'builtin_free' from 24 to 18.

	PR fortran/34143
	* gfortran.dg/alloc_comp_constructor_5.f90 : New test.

	PR fortran/32795
	* gfortran.dg/alloc_comp_constructor_4.f90 : New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_2.f90
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_constructor_4.f90
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_constructor_5.f90
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_constructor_6.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90

Comment 15 Tobias Burnus 2008-11-27 13:21:40 UTC
I think PR is fixed on the trunk (4.4) [-> back porting?], except of the issue of comment 13 (-> different PR?).
Comment 16 Paul Thomas 2008-11-29 20:43:49 UTC
Subject: Bug 34143

Author: pault
Date: Sat Nov 29 20:42:22 2008
New Revision: 142284

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142284
Log:
2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34820
	* trans-expr.c (gfc_conv_function_call): Remove all code to
	deallocate intent out derived types with allocatable
	components.
	(gfc_trans_assignment_1): An assignment from a scalar to an
	array of derived types with allocatable components, requires
	a deep copy to each array element and deallocation of the
	converted rhs expression afterwards.
	* trans-array.c : Minor whitespace.
	* trans-decl.c (init_intent_out_dt): Add code to deallocate
	allocatable components of derived types with intent out.
	(generate_local_decl): If these types are unused, set them
	referenced anyway but allow the uninitialized warning.

	PR fortran/34143
	* trans-expr.c (gfc_trans_subcomponent_assign): If a conversion
	expression has a null data pointer argument, nullify the
	allocatable component.

	PR fortran/32795
	* trans-expr.c (gfc_trans_subcomponent_assign): Only nullify
	the data pointer if the source is not a variable.

2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34820
	* gfortran.dg/alloc_comp_constructor_6.f90 : New test.
	* gfortran.dg/alloc_comp_basics_1.f90 : Reduce expected refs to
	'builtin_free' from 24 to 18.

	PR fortran/34143
	* gfortran.dg/alloc_comp_constructor_5.f90 : New test.

	PR fortran/32795
	* gfortran.dg/alloc_comp_constructor_4.f90 : New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_2.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/alloc_comp_constructor_4.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/alloc_comp_constructor_5.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/alloc_comp_constructor_6.f90
Modified:
    branches/gcc-4_3-branch/gcc/fortran/ChangeLog
    branches/gcc-4_3-branch/gcc/fortran/trans-array.c
    branches/gcc-4_3-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_3-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90

Comment 17 Paul Thomas 2008-11-30 07:50:36 UTC
Fixed on trunk and 4.3.

Comment #13 has migrated to PR38324.

Thanks for the report

Paul