User account creation filtered due to spam.

Bug 53643 - [OOP] ICE (segfault) with INTENT(OUT) CLASS array
Summary: [OOP] ICE (segfault) with INTENT(OUT) CLASS array
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2012-06-12 08:43 UTC by Tobias Burnus
Modified: 2012-06-13 12:15 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-06-12 08:43:21 UTC
Found by Alessandro Fanfarillo and me, cf. http://gcc.gnu.org/ml/fortran/2012-06/msg00070.html

The following program gives an ICE (segfault)

type t
  integer, allocatable :: comp
end type t
contains
  subroutine foo(x)
    class(t), allocatable, intent(out) :: x(:)
  end subroutine
end



Untested draft patch:

--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -3453,8 +3453,3 @@ init_intent_out_dt (gfc_symbol * proc_sym,
       {
-       tree decl = build_fold_indirect_ref_loc (input_location,
-                                                f->sym->backend_decl);
-       tmp = CLASS_DATA (f->sym)->backend_decl;
-       tmp = fold_build3_loc (input_location, COMPONENT_REF,
-                              TREE_TYPE (tmp), decl, tmp, NULL_TREE);
-       tmp = build_fold_indirect_ref_loc (input_location, tmp);
+       tmp = gfc_class_data_get (f->sym->backend_decl);
        tmp = gfc_deallocate_alloc_comp (CLASS_DATA (f->sym)->ts.u.derived,
Comment 1 Tobias Burnus 2012-06-12 09:50:40 UTC
The patch fails at run time for  gfortran.dg/typebound_operator_13.f03  in assign. In GCC 4.7, the generated code is:
  if (lhs->_data->position.data != 0B)

With 4.8 and the patch, one has:
  if (lhs->_data.position.data != 0B)
               ^^^
Comment 2 Tobias Burnus 2012-06-12 12:33:34 UTC
I am not sure whether the following (in trans-decl.c) is the proper fix or an ugly work around, but it seems to work. -- Maybe, a proper fix would be to modify the following "if" block in trans-array.c's structure_alloc_comps?

  if ((POINTER_TYPE_P (decl_type) && rank != 0)
        || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
    decl = build_fold_indirect_ref_loc (input_location,
                                    decl);

 * * *

The scalar coarray version does not seem to work; using an array coarray seems to be okay. My impression is that structure_alloc_comps simply doesn't handle coarrays types correctly. (Coarray components is a different issue and currently not properly supported at all.) See trans-array.c part of the patch below.

  type t
    integer, allocatable :: comp
  end type t
  contains
    subroutine foo(x)
      class(t), intent(out) :: x[*]
    end subroutine
  end


--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -3453,8 +3453,5 @@ init_intent_out_dt (gfc_symbol * proc_sym, gfc_wrapped_block * block)
       {
-       tree decl = build_fold_indirect_ref_loc (input_location,
-                                                f->sym->backend_decl);
-       tmp = CLASS_DATA (f->sym)->backend_decl;
-       tmp = fold_build3_loc (input_location, COMPONENT_REF,
-                              TREE_TYPE (tmp), decl, tmp, NULL_TREE);
-       tmp = build_fold_indirect_ref_loc (input_location, tmp);
+       tmp = gfc_class_data_get (f->sym->backend_decl);
+       if (CLASS_DATA (f->sym)->as == NULL)
+         tmp = build_fold_indirect_ref_loc (input_location, tmp);
        tmp = gfc_deallocate_alloc_comp (CLASS_DATA (f->sym)->ts.u.derived,
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -7320,5 +7320,3 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
        || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
-
-    decl = build_fold_indirect_ref_loc (input_location,
-                                   decl);
+    decl = build_fold_indirect_ref_loc (input_location, decl);

@@ -7330,3 +7328,3 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
   if (TREE_CODE (decl_type) == ARRAY_TYPE
-       || GFC_DESCRIPTOR_TYPE_P (decl_type))
+      || (GFC_DESCRIPTOR_TYPE_P (decl_type) && rank != 0))
     {
Comment 3 Tobias Burnus 2012-06-13 11:57:51 UTC
Author: burnus
Date: Wed Jun 13 11:57:45 2012
New Revision: 188507

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188507
Log:
2012-06-13  Tobias Burnus  <burnus@net-b.de>

        PR fortran/53643
        * trans-decl.c (init_intent_out_dt): Fix for polymorphic arrays.
        * trans-array.c (structure_alloc_comps): Don't loop for
        scalar coarrays.

2012-06-13  Tobias Burnus  <burnus@net-b.de>

        PR fortran/53643
        * gfortran.dg/intent_out_7.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/intent_out_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 Tobias Burnus 2012-06-13 12:15:48 UTC
FIXED on the 4.8 trunk.