Bug 35810

Summary: [TR 15581 / F2003] Automatic reallocation on assignment to allocatable variables
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, janus, kargls, t.r.hopkins, tkoenig
Priority: P3 Keywords: wrong-code
Version: 4.3.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2008-11-10 19:46:00
Bug Depends on:    
Bug Blocks: 20585, 43366    

Description Tobias Burnus 2008-04-03 08:54:28 UTC
The following is invalid Fortran 95 but valid Fortran 2003 as the variable is reallocated:

integer, allocatable :: a(:)
allocate(a(1))
print *, size(a)
a = [1,2,3]  ! Implicit reallocation.
! Wrong: a(:) = [1,2,3] ! Out of bounds 1 vs. 3
print *, size(a)
end

The Intel compiler already supports this option. It provides the option -assume [no]realloc_lhs to switch the support on/off. "Off" is useful for bound checks and makes the program faster as the bounds do not need to be checked in that case.

See also the comp.lang.fortran post at:
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/7d5d1e7f4a48071c/7c63fef65ba5ea70?lnk=gst&q=realloc_lhs
Comment 1 Tobias Burnus 2008-04-03 09:04:17 UTC
One thing to add: Seemingly gfortran supports reallocation for allocatable components (by itself a F2003 feature) using the constructor (see example), but not without constructor.

Additionally, while a simple example (as below) works, the long example in the thread above is failing in some cases. (See link.)

type t
  integer, allocatable :: a(:)
end type t
type(t) :: a
allocate(a%a(1))
print *, size(a%a) ! print 1  (OK)
a = t([1,2,3])
print *, size(a%a) ! prints 2 (OK)
end
Comment 2 Tobias Burnus 2008-10-28 17:37:58 UTC
Segfault with return values of allocatable functions.

A code which does not work is the following TR15581-conform program.
It seqfaults (SIGABRT) and valgrind shows errors of the kind:

==12853== Invalid write of size 4
==12853==    at 0x400966: MAIN__ (aa.f90:7)
==12853==  Address 0x58e7b4c is 0 bytes after a block of size 4 alloc'd
==12853==    at 0x4C256AE: malloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==12853==    by 0x4008A4: MAIN__ (aa.f90:4)

Test case:

implicit none
integer,allocatable :: j(:)
integer :: i
allocate(j(1))
do i = 1,200000
! deallocate(j)
 j = alloc()
end do
contains
function alloc()
  integer, allocatable :: alloc(:)
  allocate(alloc(10000))
end function
end
Comment 3 Mikael Morin 2008-11-28 13:29:37 UTC
Additional test cases, probably related, to be re-checked:
PR 36463, comment 12
PR 35971, comment 0
Comment 4 Tobias Burnus 2009-06-08 09:11:30 UTC
See also:
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/fc7bdedfa4afc785

and note that the realloc shall not always happen: If <var> has TARGET attribute and the size is the same, no pointer to <var> may break.

Comment 5 kargls 2009-08-07 19:27:34 UTC
*** Bug 41003 has been marked as a duplicate of this bug. ***
Comment 6 Tobias Burnus 2009-10-16 20:23:31 UTC
Note in Fortran 2008 (cf. PR 41719),
  polymorphic-variable = expr
is allowed iff the variable is allocatable.
Comment 7 Tobias Burnus 2010-03-31 18:05:19 UTC
Note: For coarrays/coindexed variables, the shape must be the same. That means that there is _no_ reallocate on assignment, cf. F2008, "7.2.1.2 Intrinsic assignment statement":
"In an intrinsic assignment statement, [...] (3) the variable and expr shall be conformable unless the variable is an allocatable array that has the same rank as expr and is neither a coarray nor a coindexed object,"
Comment 8 Tobias Burnus 2010-08-14 09:03:54 UTC
Another test case, which requires PR45170 (allocable string lengths); it should print "|cdef|" (found at c.l.f in the thread "Problem with automatic reallocation of allocatable scalar on assignment")

   program tst
      character(len=:), allocatable :: S
      S='abcdef'
      S=S(3:)
      write(*,'("|",A,"|")')S
   end program tst 
Comment 9 Tobias Burnus 2010-10-08 16:28:39 UTC
Paul's draft patch: http://gcc.gnu.org/ml/fortran/2010-10/msg00100.html
Comment 10 Tobias Burnus 2010-10-25 22:22:49 UTC
(In reply to comment #6)
> Note in Fortran 2008 (cf. PR 41719),
>   polymorphic-variable = expr
> is allowed iff the variable is allocatable.

And note further that this is nontrivial as it requires a deep copy, cf. PR 46174.

  * * *

Newer draft patch for realloc on assignment (w/o the polymorphic assignment):
http://gcc.gnu.org/ml/fortran/2010-10/msg00213.html
Comment 11 Paul Thomas 2010-11-28 13:47:31 UTC
Author: pault
Date: Sun Nov 28 13:47:26 2010
New Revision: 167220

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

	 PR fortran/35810
	* trans-array.c (gfc_trans_array_constructor): If the loop->to
	is a VAR_DECL, assume this is dynamic. In this case, use the
	counter to obtain the value and set loop->to appropriately.
	(gfc_conv_ss_descriptor): Always save the offset of a variable
	in info.saved_offset.
	(gfc_conv_ss_startstride): Do not attempt bound checking of the
	lhs of an assignment, if allocatable and f2003 is allowed.
	(gfc_conv_loop_setup): If possible, do not use an allocatable
	lhs variable for the loopspec.
	(gfc_is_reallocatable_lhs): New function.
	(get_std_lbound): New function.
	(gfc_alloc_allocatable_for_assignment): New function.
	* gfortran.h : Add flag_realloc_lhs to the options structure.
	* lang.opt : Add option f(no-)realloc-lhs.
	* invoke.texi : Document option f(no-)realloc-lhs.
	* options.c (gfc_init_options, gfc_post_options,
	gfc_handle_option): Incorporate f(no-)realloc-lhs with default
	to frealloc_lhs for -std > f95.
	* trans-array.h : Add primitive for previous.
	* trans-expr.c (gfc_conv_string_length): Return if character
	length is a variable and the expression is NULL.
	(gfc_conv_procedure_call): If the call is of the kind x = f(...)
	and the lhs is allocatable and reallocation on assignment OK,
	call gfc_alloc_allocatable_for_assignment. Do not generate the
	function call unless direct by reference.
	(realloc_lhs_loop_for_fcn_call): New function.
	(realloc_lhs_bounds_for_intrinsic_call): New function.
	(gfc_trans_arrayfunc_assign): Reallocation assignments need
	a loopinfo and for the loop bounds to be set.  With intrinsic
	functions, free the lhs data and let the library allocate the
	data array. Done by the new functions above.
	(gfc_trans_assignment_1): If the lhs is allocatable and
	reallocation on assignment is allowed, mark the lhs and use
	gfc_alloc_allocatable_for_assignment to make the reallocation.
	* trans.h : Add is_alloc_lhs bitfield to gfc_ss structure.

2010-11-28  Paul Thomas  <pault@gcc.gnu.org

	PR fortran/35810
	* gfortran.dg/realloc_on_assign_1.f03: New test.
	* gfortran.dg/realloc_on_assign_2.f03: New test.
	* gfortran.dg/transpose_2.f90: dg-option -fno-realloc-lhs.
	* gfortran.dg/unpack_bounds_1.f90: The same.
	* gfortran.dg/cshift_bounds_2.f90: The same.
	* gfortran.dg/matmul_bounds_2.f90: The same.
	* gfortran.dg/matmul_bounds_3.f90: The same.
	* gfortran.dg/matmul_bounds_4.f90: The same.
	* gfortran.dg/matmul_bounds_5.f90: The same.

Added:
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_1.f03
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/invoke.texi
    trunk/gcc/fortran/lang.opt
    trunk/gcc/fortran/options.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-array.h
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/cshift_bounds_2.f90
    trunk/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90
    trunk/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90
    trunk/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90
    trunk/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90
    trunk/gcc/testsuite/gfortran.dg/transpose_2.f90
    trunk/gcc/testsuite/gfortran.dg/unpack_bounds_1.f90
Comment 12 janus 2010-12-30 12:18:14 UTC
Note: realloc_on_assign_2.f03 fails on current trunk when building with --disable-bootstrap (system compiler: gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292]):

realloc_on_assign_2.f03: In function ‘test5’:
realloc_on_assign_2.f03:101:0: internal compiler error: in fold_convert_loc, at fold-const.c:1906


Reduced test case:

program test5
  real, allocatable, dimension (:,:) :: xwrkt
  xwrkt = trs2a2 ()
contains
  function trs2a2 ()
    real, dimension (1:2,1:2) :: trs2a2
    trs2a2 = 0.0
  end function
end
Comment 13 Tobias Burnus 2011-01-27 21:03:24 UTC
Submitted patch for (re)allocate on intrinsic assignment -- now for scalars:
  http://gcc.gnu.org/ml/fortran/2011-01/msg00264.html
Also supports (for scalars only) deferred-length character strings.
Comment 14 Paul Thomas 2011-01-28 13:53:25 UTC
Author: pault
Date: Fri Jan 28 13:53:19 2011
New Revision: 169356

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169356
Log:
2011-01-28  Paul Thomas  <pault@gcc.gnu.org>
	    Tobias Burnus  <burnus@gcc.gnu.org>

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* interface.c (compare_actual_formal): An allocatable or pointer
	deferred length actual is only allowed if the formal argument
	is also deferred length. Clean up whitespace.
	* trans-expr.c (gfc_conv_procedure_call): Pass string length for
	deferred character length formal arguments by reference. Do the
	same for function results.
	(gfc_trans_pointer_assignment): Do not do runtime check of lhs
	and rhs character lengths, if deferred length lhs.  In this case
	set the lhs character length to that of the rhs.
	(gfc_conv_string_parameter): Remove assert that string length is
	an integer type.
	(is_scalar_reallocatable_lhs): New function.
	(alloc_scalar_allocatable_for_assignment): New function.
	(gfc_trans_assignment_1): Call above new function. If the rhs is
	a deferred character length itself, makes ure that the function
	is called before reallocation, so that the length is available.
	(gfc_trans_asssignment): Remove error about assignment to
	deferred length character variables.
	* gfortran.texi : Update entry about (re)allocation on
	assignment.
	* trans-stmt.c (gfc_trans_allocate): Add code to handle deferred
	length character variables.
	* module.c (mio_typespec): Transfer deferred characteristic.
	* trans-types.c (gfc_get_function_type): New code to generate
	hidden typelist, so that those character lengths that are
	passed by reference get the right type.
	* resolve.c (resolve_contained_fntype): Supress error for
	deferred character length functions.
	(resolve_function, resolve_fl_procedure) The same.
	(check_symbols): Remove the error that support for
	entity with deferred type parameter is not yet implemented.
	(resolve_fl_derived): The same.
	match.c (alloc_opt_list): Allow MOLD for deferred length object.
	* trans-decl.c (gfc_get_symbol_decl): For deferred character
	length dummies, generate a local variable for string length.
	(create_function_arglist): Hidden length can be a pointer.
	(gfc_trans_deferred_vars): For deferred character length
	results and dummies, assign the string length to the local
	variable from the hidden argument on entry and the other way
	round on exit, as appropriate.

2011-01-28  Paul Thomas  <pault@gcc.gnu.org>
	    Tobias Burnus  <burnus@gcc.gnu.org>

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/realloc_on_assign_3.f03: New test.
	* gfortran.dg/realloc_on_assign_4.f03: New test.
	* gfortran.dg/realloc_on_assign_5.f90: New test.
	* gfortran.dg/allocatable_function_5.f90: New test.
	* gfortran.dg/allocate_deferred_char_scalar_1.f90: New test.
	* gfortran.dg/deferred_type_param_2.f90: Remove two "not yet
	implemented" dg-errors.


Added:
    trunk/gcc/testsuite/gfortran.dg/allocate_deferred_char_scalar_1.f03
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_3.f03
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_4.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.texi
    trunk/gcc/fortran/interface.c
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/deferred_type_param_2.f90
Comment 15 Tobias Burnus 2011-01-28 14:59:03 UTC
Close as FIXED (for the 4.6 trunk).

Left overs:
- ICE mentioned in comment 12 - now PR 47516
- Assignment to polymorphic LHS, PR 43366
Comment 16 Tobias Burnus 2011-01-28 14:59:46 UTC
really mark as FIXED.
Comment 17 Tobias Burnus 2011-01-28 15:35:05 UTC
Another follow up:
Bug 47517  - the example from c.l.f linked to from comment 0 fails
Comment 18 Paul Thomas 2011-01-30 17:50:07 UTC
Author: pault
Date: Sun Jan 30 17:50:01 2011
New Revision: 169413

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169413
Log:
2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/allocatable_function_5.f90: New test not added by
	mistake on 2011-01-28.



Added:
    trunk/gcc/testsuite/gfortran.dg/allocatable_function_5.f90
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_5.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 19 Diego Novillo 2011-02-02 17:59:36 UTC
Author: dnovillo
Date: Wed Feb  2 17:59:29 2011
New Revision: 169666

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169666
Log:
2011-01-28  Paul Thomas  <pault@gcc.gnu.org>
	    Tobias Burnus  <burnus@gcc.gnu.org>

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* interface.c (compare_actual_formal): An allocatable or pointer
	deferred length actual is only allowed if the formal argument
	is also deferred length. Clean up whitespace.
	* trans-expr.c (gfc_conv_procedure_call): Pass string length for
	deferred character length formal arguments by reference. Do the
	same for function results.
	(gfc_trans_pointer_assignment): Do not do runtime check of lhs
	and rhs character lengths, if deferred length lhs.  In this case
	set the lhs character length to that of the rhs.
	(gfc_conv_string_parameter): Remove assert that string length is
	an integer type.
	(is_scalar_reallocatable_lhs): New function.
	(alloc_scalar_allocatable_for_assignment): New function.
	(gfc_trans_assignment_1): Call above new function. If the rhs is
	a deferred character length itself, makes ure that the function
	is called before reallocation, so that the length is available.
	(gfc_trans_asssignment): Remove error about assignment to
	deferred length character variables.
	* gfortran.texi : Update entry about (re)allocation on
	assignment.
	* trans-stmt.c (gfc_trans_allocate): Add code to handle deferred
	length character variables.
	* module.c (mio_typespec): Transfer deferred characteristic.
	* trans-types.c (gfc_get_function_type): New code to generate
	hidden typelist, so that those character lengths that are
	passed by reference get the right type.
	* resolve.c (resolve_contained_fntype): Supress error for
	deferred character length functions.
	(resolve_function, resolve_fl_procedure) The same.
	(check_symbols): Remove the error that support for
	entity with deferred type parameter is not yet implemented.
	(resolve_fl_derived): The same.
	match.c (alloc_opt_list): Allow MOLD for deferred length object.
	* trans-decl.c (gfc_get_symbol_decl): For deferred character
	length dummies, generate a local variable for string length.
	(create_function_arglist): Hidden length can be a pointer.
	(gfc_trans_deferred_vars): For deferred character length
	results and dummies, assign the string length to the local
	variable from the hidden argument on entry and the other way
	round on exit, as appropriate.

2011-01-28  Paul Thomas  <pault@gcc.gnu.org>
	    Tobias Burnus  <burnus@gcc.gnu.org>

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/realloc_on_assign_3.f03: New test.
	* gfortran.dg/realloc_on_assign_4.f03: New test.
	* gfortran.dg/realloc_on_assign_5.f90: New test.
	* gfortran.dg/allocatable_function_5.f90: New test.
	* gfortran.dg/allocate_deferred_char_scalar_1.f90: New test.
	* gfortran.dg/deferred_type_param_2.f90: Remove two "not yet
	implemented" dg-errors.

Added:
    branches/google/integration/gcc/testsuite/gfortran.dg/allocate_deferred_char_scalar_1.f03
    branches/google/integration/gcc/testsuite/gfortran.dg/realloc_on_assign_3.f03
    branches/google/integration/gcc/testsuite/gfortran.dg/realloc_on_assign_4.f03
Modified:
    branches/google/integration/gcc/fortran/ChangeLog
    branches/google/integration/gcc/fortran/gfortran.texi
    branches/google/integration/gcc/fortran/interface.c
    branches/google/integration/gcc/fortran/match.c
    branches/google/integration/gcc/fortran/module.c
    branches/google/integration/gcc/fortran/resolve.c
    branches/google/integration/gcc/fortran/trans-decl.c
    branches/google/integration/gcc/fortran/trans-expr.c
    branches/google/integration/gcc/fortran/trans-stmt.c
    branches/google/integration/gcc/fortran/trans-types.c
    branches/google/integration/gcc/testsuite/ChangeLog
    branches/google/integration/gcc/testsuite/gfortran.dg/deferred_type_param_2.f90
Comment 20 Diego Novillo 2011-02-02 18:04:44 UTC
Author: dnovillo
Date: Wed Feb  2 18:04:21 2011
New Revision: 169697

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169697
Log:
2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/allocatable_function_5.f90: New test not added by
	mistake on 2011-01-28.

Added:
    branches/google/integration/gcc/testsuite/gfortran.dg/allocatable_function_5.f90
    branches/google/integration/gcc/testsuite/gfortran.dg/realloc_on_assign_5.f03
Modified:
    branches/google/integration/gcc/fortran/ChangeLog
    branches/google/integration/gcc/fortran/trans-expr.c
    branches/google/integration/gcc/testsuite/ChangeLog