Bug 57456 - [OOP] CLASS + CHARACTER ALLOCATE with typespec: For arrays, the typespec is ignored
Summary: [OOP] CLASS + CHARACTER ALLOCATE with typespec: For arrays, the typespec is i...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, wrong-code
Depends on:
Blocks: 51976 58754
  Show dependency treegraph
 
Reported: 2013-05-29 17:16 UTC by Tobias Burnus
Modified: 2016-11-16 17:39 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2013-05-29 17:16:29 UTC
The following seems to ignore the typespec ("t2::") when calculating how much memory is required to allocate:


module m
  implicit none
  type t
    integer :: i
   end type t
  type, extends(t) :: t2
    integer :: j
   end type t2
end module m

program test
  use m
  implicit none
  integer :: i
  class(t), save, allocatable :: y(:)

  allocate (t2 :: y(5)) ! Should malloc 2*4*5 = 40 bytes, mallocs only 20
  select type(y)
  type is (t2)
    do i = 1, 5
      y(i)%i = i ! "Invalid write of size 4"
    end do
  end select
  deallocate(y) ! SIGABRT: Process abort signal.
end
Comment 1 Tobias Burnus 2013-05-29 17:17:40 UTC
Note: It works if one uses a scalar instead of an array.
Comment 2 Tobias Burnus 2013-05-29 17:59:35 UTC
There is a similar problem for:

character(len=:), allocatable :: str(:)
allocate (character(len=5) :: str(5))
end

 * * *

To solve this properly, one should put all the logic into gfc_trans_allocate - and avoid duplicating it in gfc_array_init_size (which is called from gfc_array_allocate, which is called from the mentioned gfc_trans_allocate).

Note: Also the evaluation of the type-spec length should be done only once for
  allocate (character(len = f()) :: str(5), str2, str3, str4(10))
Comment 3 Dominique d'Humieres 2013-06-27 21:35:40 UTC
Is not this PR supposed to have been fixed (partially) by revision 199528?

Revision 199528

Author:	burnus
Date:	Fri May 31 09:41:53 2013 UTC (3 weeks, 6 days ago)
Changed paths:	6
Log Message:	
2013-05-31  Tobias Burnus  <burnus@net-b.de>

        PR fortran/57456
        * trans-array.c (gfc_array_init_size): Use passed type spec,
        when available.
        (gfc_array_allocate): Pass typespec on.
        * trans-array.h (gfc_array_allocate): Update prototype.
        * trans-stmt.c (gfc_trans_allocate): Pass typespec on.

2013-05-31  Tobias Burnus  <burnus@net-b.de>

        PR fortran/57456
        * gfortran.dg/class_array_17.f90: New.

Note that the problem in comment #2 is still there at revision 200486.
Comment 4 Tobias Burnus 2013-06-27 21:46:10 UTC
(In reply to Dominique d'Humieres from comment #3)
> Is not this PR supposed to have been fixed (partially) by revision 199528?

Yes. The patch fixes the derived-type issue - but it doesn't solve the CHARACTER issue. As written in comment 2, the proper way is use one common code in gfc_trans_allocate, which calculates the byte size, and use it both for scalars (directly in gfc_trans_allocate) and for arrays in gfc_array_allocate -> gfc_array_init_size. (One also should evaluate the LEN= expression only once.)
Comment 6 Andre Vehreschild 2015-03-24 10:29:19 UTC
Author: vehre
Date: Tue Mar 24 10:28:48 2015
New Revision: 221621

URL: https://gcc.gnu.org/viewcvs?rev=221621&root=gcc&view=rev
Log:
gcc/fortran/ChangeLog

2015-03-24  Andre Vehreschild  <vehre@gmx.de>

	PR fortran/64787
	PR fortran/57456
	PR fortran/63230
	* class.c (gfc_add_component_ref):  Free no longer needed
	ref-chains to prevent memory loss.
	(find_intrinsic_vtab): For deferred length char arrays or
	unlimited polymorphic objects, store the size in bytes of one
	character in the size component of the vtab.
	* gfortran.h: Added gfc_add_len_component () define.
	* trans-array.c (gfc_trans_create_temp_array): Switched to new
	function name for getting a class' vtab's field.
	(build_class_array_ref): Likewise.
	(gfc_array_init_size): Using the size information from allocate
	more consequently now, i.e., the typespec of the entity to
	allocate is no longer needed.  This is to address the last open
	comment in PR fortran/57456.
	(gfc_array_allocate): Likewise.
	(structure_alloc_comps): gfc_copy_class_to_class () needs to
	know whether the class is unlimited polymorphic.
	* trans-array.h: Changed interface of gfc_array_allocate () to
	reflect the no longer needed typespec.
	* trans-expr.c (gfc_find_and_cut_at_last_class_ref): New.
	(gfc_reset_len): New.
	(gfc_get_class_array_ref): Switch to new function name for
	getting a class' vtab's field.
	(gfc_copy_class_to_class):  Added flag to know whether the class
	to copy is unlimited polymorphic.  Adding _len dependent code
	then, which calls ->vptr->copy () with four arguments adding
	the length information ->vptr->copy(from, to, from_len, to_cap).
	(gfc_conv_procedure_call): Switch to new function name for
	getting a class' vtab's field.
	(alloc_scalar_allocatable_for_assignment): Use the string_length
	as computed by gfc_conv_expr and not the statically backend_decl
	which may be incorrect when ref-ing.
	(gfc_trans_assignment_1): Use the string_length variable and
	not the rse.string_length.  The former has been computed more
	generally.
	* trans-intrinsic.c (gfc_conv_intrinsic_sizeof): Switch to new
	function name for getting a class' vtab's field.
	(gfc_conv_intrinsic_storage_size): Likewise.
	(gfc_conv_intrinsic_transfer): Likewise.
	* trans-stmt.c (gfc_trans_allocate): Restructured to evaluate
	source=expr3 only once before the loop over the objects to
	allocate, when the objects are not arrays. Doing correct _len
	initialization and calling of vptr->copy () fixing PR 64787.
	(gfc_trans_deallocate): Reseting _len to 0, preventing future
	errors.
	* trans.c (gfc_build_array_ref): Switch to new function name
	for getting a class' vtab's field.
	(gfc_add_comp_finalizer_call): Likewise.
	* trans.h: Define the prototypes for the gfc_class_vtab_*_get ()
	and gfc_vptr_*_get () functions.
	Added gfc_find_and_cut_at_last_class_ref () and
	gfc_reset_len () routine prototype.  Added flag to
	gfc_copy_class_to_class () prototype to signal an unlimited
	polymorphic entity to copy.

gcc/testsuite/ChangeLog

2015-03-24  Andre Vehreschild  <vehre@gmx.de>

	* gfortran.dg/allocate_alloc_opt_13.f90: Added tests for
	source= and mold= expressions functionality.
	* gfortran.dg/allocate_class_4.f90: New test.
	* gfortran.dg/unlimited_polymorphic_20.f90: Added test whether
	copying an unlimited polymorhpic object containing a char array
	to another unlimited polymorphic object respects the _len
	component.
	* gfortran.dg/unlimited_polymorphic_22.f90: Extended to check
	whether deferred length char array allocate works, unlimited
	polymorphic object allocation from a string works and if
	allocating an array of deferred length strings works.
	* gfortran.dg/unlimited_polymorphic_24.f03: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/allocate_class_4.f90
    trunk/gcc/testsuite/gfortran.dg/unlimited_polymorphic_24.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-array.h
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/allocate_alloc_opt_13.f90
    trunk/gcc/testsuite/gfortran.dg/unlimited_polymorphic_20.f90
    trunk/gcc/testsuite/gfortran.dg/unlimited_polymorphic_22.f90
Comment 7 Andre Vehreschild 2015-04-23 12:57:54 UTC
Fixed with commit r221621.