Bug 57117

Summary: [OOP] ICE for sourced allocation of a polymorphic entity using TRANSPOSE
Product: gcc Reporter: Bader <Bader>
Component: fortranAssignee: vehre
Status: RESOLVED FIXED    
Severity: normal CC: burnus, janus, pault, vehre
Priority: P4 Keywords: ice-on-valid-code
Version: 4.8.0   
Target Milestone: 7.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2013-04-29 00:00:00
Attachments: module and main program as standalone source.
Draft patch for the PR
A completely different approach to the fix.
Shorter version to fix the issue.

Description Bader@lrz.de 2013-04-29 19:59:46 UTC
Created attachment 29977 [details]
module and main program as standalone source.

The attached source code causes a segfault in gfortran at compile time: 

intrinsics_02_pos.f90:61:0: internal compiler error: Segmentation fault
   allocate(y(3,3), source=transpose(x))
0x87e07f crash_signal             
        ../../gcc-4.8.0/gcc/toplev.c:332
0x5ad22b gfc_conv_scalarized_array_ref
        ../../gcc-4.8.0/gcc/fortran/trans-array.c:3037
0x5adb89 gfc_conv_array_ref(gfc_se*, gfc_array_ref*, gfc_symbol*, locus*)
        ../../gcc-4.8.0/gcc/fortran/trans-array.c:3172
0x5d0cdf gfc_conv_variable
        ../../gcc-4.8.0/gcc/fortran/trans-expr.c:1809
0x5cddaa gfc_conv_expr(gfc_se*, gfc_expr*)
        ../../gcc-4.8.0/gcc/fortran/trans-expr.c:6266
0x5e158c gfc_conv_intrinsic_function(gfc_se*, gfc_expr*)
        ../../gcc-4.8.0/gcc/fortran/trans-intrinsic.c:6697
0x5cd832 gfc_conv_function_expr
        ../../gcc-4.8.0/gcc/fortran/trans-expr.c:5547
0x5cdd1a gfc_conv_expr(gfc_se*, gfc_expr*)
        ../../gcc-4.8.0/gcc/fortran/trans-expr.c:6258
0x5d1d05 gfc_conv_expr_reference(gfc_se*, gfc_expr*)
        ../../gcc-4.8.0/gcc/fortran/trans-expr.c:6387
0x5f30be gfc_trans_allocate(gfc_code*)
        ../../gcc-4.8.0/gcc/fortran/trans-stmt.c:4911
0x5a7647 trans_code
        ../../gcc-4.8.0/gcc/fortran/trans.c:1577
0x5c4be2 gfc_generate_function_code(gfc_namespace*)
        ../../gcc-4.8.0/gcc/fortran/trans-decl.c:5397
0x568880 translate_all_program_units
        ../../gcc-4.8.0/gcc/fortran/parse.c:4468
0x568880 gfc_parse_file()
        ../../gcc-4.8.0/gcc/fortran/parse.c:4682
0x5a3c25 gfc_be_parse_file
        ../../gcc-4.8.0/gcc/fortran/f95-lang.c:189
Comment 1 Dominique d'Humieres 2013-04-29 21:34:28 UTC
Confirmed. If I comment out the block

  call construct(x, 1)

  allocate(y(3,3), source=transpose(x))
  select type (y)
  type is(ti)
     if (y(3,1)%i /= 7) ok(5) = .false.
  class default
     ok(6) = .false.
  end select
  deallocate(y)  <--- it should be deallocate(x, y) otherwise call construct(x, 2) complains

then I get the following ICE

pr57117_db.f90: In function 'intr_02':
pr57117_db.f90:86:0: internal compiler error: in gfc_conv_procedure_call, at fortran/trans-expr.c:4888
   allocate(z(9), source=reshape(x, (/ 9 /)))
Comment 2 janus 2013-04-30 12:22:40 UTC
Also this one can be triggered without UP:


  implicit none
  
  type :: ti
  end type

  class(ti), allocatable :: x(:,:), y(:,:)

  allocate(y(3,3), source=transpose(x))

end
Comment 3 Dominique d'Humieres 2013-04-30 16:39:38 UTC
Reduced test for RESHAPE:

  implicit none

  type :: ti
  end type

  class(ti), allocatable :: x(:,:), z(:)

  allocate(z(9), source=reshape(x, (/ 9 /)))

end

pr57117_2.f90:8:0: internal compiler error: in gfc_conv_procedure_call, at fortran/trans-expr.c:4902
   allocate(z(9), source=reshape(x, (/ 9 /)))
Comment 4 Paul Thomas 2015-10-25 15:54:29 UTC
The result from the reshape call is completely screwed up. The temporary, is descriptor, whose data field is class objects, rather than returning the _data field of the class object.

I can see how to fix this.

Paul
Comment 5 Paul Thomas 2015-10-28 14:57:56 UTC
Created attachment 36609 [details]
Draft patch for the PR

The two TODOs should be noted. These must be fixed before submission. However, this patch does regtest without regressions.

The following version of the testcase runs correctly.

Cheers

Paul

  implicit none
  integer :: j, k
  type :: ti
   real(8) :: r
  end type
  type, extends (ti) :: ri
    integer :: i
  end type
  class(ti), allocatable :: x(:,:), z(:)

  allocate (z, source = [(ti (real (j)), j = 1, 9)])
  allocate(x(3,3), source=reshape(z, (/ 3,3 /)))
  call foo
  deallocate (z, x)

  allocate (z, source = [(ri (real (j), j), j = 1, 9)])
  allocate(x(3,3), source=reshape(z, (/ 3,3 /)))
  call foo
  deallocate (z, x)

contains
  subroutine foo
    select type (x)
      type is (ti)
        print *, "ti"
        print *, x%r
      type is (ri)
        print *, "ri"
        print *, x%r
        print *, x%i
      class default
        call abort
    end select
  end subroutine
end
Comment 6 Dominique d'Humieres 2015-10-28 17:24:05 UTC
> Created attachment 36609 [details]
> Draft patch for the PR

With this patch, the tests in this PR compile. However it seems that there is a remaining issue with "allocate(y(3,3), source=transpose(x))": running the original test outputs

 FAIL:  T T T T F T T T T T T T T T T

'y' seems to be filled with 'x' and not 'transpose(x)'.
Comment 7 paul.richard.thomas@gmail.com 2015-10-28 19:03:47 UTC
Dear Dominique,

That is entirely possible. I concentrated exclusively on reshape. I
will have a look at the original problem later.

Thanks a lot

Paul


On 28 October 2015 at 18:24, dominiq at lps dot ens.fr
<gcc-bugzilla@gcc.gnu.org> wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57117
>
> --- Comment #6 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
>> Created attachment 36609 [details]
>> Draft patch for the PR
>
> With this patch, the tests in this PR compile. However it seems that there is a
> remaining issue with "allocate(y(3,3), source=transpose(x))": running the
> original test outputs
>
>  FAIL:  T T T T F T T T T T T T T T T
>
> 'y' seems to be filled with 'x' and not 'transpose(x)'.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
> You are the assignee for the bug.
Comment 8 Dominique d'Humieres 2015-10-29 12:33:29 UTC
Related to/duplicate of pr55824? Still fails for "allocate(vector,source=pack(array,.true.))".
Comment 9 Paul Thomas 2015-10-29 19:01:57 UTC
Created attachment 36618 [details]
A completely different approach to the fix.

This one does far better and is less invasive. It is not yet regtested but I am certain that any problems will be trivial.

I will try with other transformational intrinsics than transpose and rehape, whilst on tonight's flight to London.

Cheers

Paul
Comment 10 Dominique d'Humieres 2015-10-30 08:38:51 UTC
> Created attachment 36618 [details]
>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36618&action=edit
> A completely different approach to the fix.
>
> This one does far better and is less invasive. It is not yet regtested
> but I am certain that any problems will be trivial.

This patch does not like reshape and pack.
Comment 11 paul.richard.thomas@gmail.com 2015-10-30 09:29:02 UTC
Dear Dominique,

That's odd, it does fine with reshape on my machine ****sigh****

Could you send me the error, please?

pack generates a completely new ICE in the most peculiar place.

I have to put this on one side for a few days. I feel that I have got
to the core of the problem.but need to sort out the implementation.

With best regards

Paul

On 30 October 2015 at 09:38, dominiq at lps dot ens.fr
<gcc-bugzilla@gcc.gnu.org> wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57117
>
> --- Comment #10 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
>> Created attachment 36618 [details]
>>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36618&action=edit
>> A completely different approach to the fix.
>>
>> This one does far better and is less invasive. It is not yet regtested
>> but I am certain that any problems will be trivial.
>
> This patch does not like reshape and pack.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
> You are the assignee for the bug.
Comment 12 Dominique d'Humieres 2015-10-30 09:39:01 UTC
> That's odd, it does fine with reshape on my machine ****sigh****

Are you sure to have attached the right patch?

> Could you send me the error, please?

Compiling the test in comment 5 gives

pr57117_3.f90:12:0:

   allocate(x(3,3), source=reshape(z, (/ 3,3 /)))
1
internal compiler error: Segmentation fault: 11

The backtrace is

#0  0x000000010010d6fc in vptr_field_get(tree_node*, int) ()
#1  0x0000000100114003 in gfc_copy_class_to_class(tree_node*, tree_node*, tree_node*, bool) ()
#2  0x000000010016615e in gfc_trans_allocate(gfc_code*) ()
#3  0x00000001000d7798 in trans_code(gfc_code*, tree_node*) ()
#4  0x000000010010a0b6 in gfc_generate_function_code(gfc_namespace*) ()
#5  0x000000010008cd4c in gfc_parse_file() ()
#6  0x00000001000d407b in gfc_be_parse_file() ()
#7  0x0000000100ae893a in compile_file() ()
#8  0x0000000100fbafcc in toplev::main(int, char**) ()
#9  0x0000000100fbc989 in main ()
Comment 13 vehre 2016-09-07 13:40:55 UTC
Created attachment 39581 [details]
Shorter version to fix the issue.

Hi all,

Dominique pointed out, that the patches proposed by Paul conflict with my accaf patch. I took a look and found a less-intrusive version to fix this issue.

Note!!! This patch is base on my patch for pr72832 available from:

https://gcc.gnu.org/ml/fortran/2016-09/msg00007.html

Bootstraps and regtests ok on x86_64-linux/F23. I haven't tested this patch in combination with my accaf patch yet (time constraints).

- Andre
Comment 14 Dominique d'Humieres 2016-09-07 16:42:39 UTC
> Created attachment 39581 [details]
> Shorter version to fix the issue.
> ...

The patch fixes the ICEs, but generates wrong-code for the original test: the output at run time is

 FAIL:  T T T T F T T T T T T T T T T

Same thing for the test in comment 5:

 ti
   1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        5.0000000000000000        6.0000000000000000        7.0000000000000000        8.0000000000000000        9.0000000000000000     
 ri
   1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        5.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000     
           1           2           3           4           0           0           0           0           0
Comment 15 vehre 2016-10-22 12:34:11 UTC
Author: vehre
Date: Sat Oct 22 12:33:38 2016
New Revision: 241439

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

2016-10-22  Andre Vehreschild  <vehre@gcc.gnu.org>

	PR fortran/43366
	PR fortran/51864
	PR fortran/57117
	PR fortran/61337
	PR fortran/61376
	* primary.c (gfc_expr_attr): For transformational functions on classes
	get the attrs from the class argument.
	* resolve.c (resolve_ordinary_assign): Remove error message due to
	feature implementation.  Rewrite POINTER_ASSIGNS to ordinary ones when
	the right-hand side is scalar class object (with some restrictions).
	* trans-array.c (trans_array_constructor): Create the temporary from
	class' inner type, i.e., the derived type.
	(build_class_array_ref): Add support for class array's storage of the
	class object or the array descriptor in the decl saved descriptor.
	(gfc_conv_expr_descriptor): When creating temporaries for class objects
	add the class object's handle into the decl saved descriptor.
	(structure_alloc_comps): Use the common way to get the _data component.
	(gfc_is_reallocatable_lhs): Add notion of allocatable class objects.
	* trans-expr.c (gfc_find_and_cut_at_last_class_ref): Remove the only ref
	only when the expression's type is BT_CLASS.
	(gfc_trans_class_init_assign): Correctly handle class arrays.
	(gfc_trans_class_assign): Joined into gfc_trans_assignment_1.
	(gfc_conv_procedure_call): Support for class types as arguments.
	(trans_get_upoly_len): For unlimited polymorphics retrieve the _len
	component's tree.
	(trans_class_vptr_len_assignment): Catch all ways to assign the _vptr
	and _len components of a class object correctly.
	(pointer_assignment_is_proc_pointer): Identify assignments of
	procedure pointers.
	(gfc_trans_pointer_assignment): Enhance support for class object pointer
	assignments.
	(gfc_trans_scalar_assign): Removed assert.
	(trans_class_assignment): Assign to a class object.
	(gfc_trans_assignment_1): Treat class objects correctly.
	(gfc_trans_assignment): Propagate flags to trans_assignment_1.
	* trans-stmt.c (gfc_trans_allocate): Use gfc_trans_assignment now
	instead of copy_class_to_class.
	* trans-stmt.h: Function prototype removed.
	* trans.c (trans_code): Less special casing for class objects.
	* trans.h: Added flags to gfc_trans_assignment () prototype.

gcc/testsuite/ChangeLog:

2016-10-22  Andre Vehreschild  <vehre@gcc.gnu.org>

        Forgot to add on original commit.
        * gfortran.dg/coarray_alloc_comp_2.f08: New test.

2016-10-22  Andre Vehreschild  <vehre@gcc.gnu.org>

	PR fortran/43366
	PR fortran/57117
	PR fortran/61337
	* gfortran.dg/alloc_comp_class_5.f03: New test.
	* gfortran.dg/class_allocate_21.f90: New test.
	* gfortran.dg/class_allocate_22.f90: New test.
	* gfortran.dg/realloc_on_assign_27.f08: New test.



Added:
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_class_5.f03
    trunk/gcc/testsuite/gfortran.dg/class_allocate_21.f90
    trunk/gcc/testsuite/gfortran.dg/class_allocate_22.f90
    trunk/gcc/testsuite/gfortran.dg/coarray_alloc_comp_2.f08
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_27.f08
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/primary.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans-stmt.h
    trunk/gcc/fortran/trans.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog
Comment 16 vehre 2016-10-24 17:00:11 UTC
Waiting one week for regression reports.
Comment 17 vehre 2016-10-31 16:26:02 UTC
No complaints so far, closing.