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.
The test case given here passes for me on x86-64 with both -m32 and -m64 and with or without -fdefault-integer-8. hmm!
(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?
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
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
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?
(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")
(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
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
I've knocked back it's priority but have assigned it to myself to compensate. Paul
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
> 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."
(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
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
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
I think PR is fixed on the trunk (4.4) [-> back porting?], except of the issue of comment 13 (-> different PR?).
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
Fixed on trunk and 4.3. Comment #13 has migrated to PR38324. Thanks for the report Paul