[Patch, fortran] PR 64757 - [5 Regression] ICE in fold_convert_loc, at fold-const.c:2353
Paul Richard Thomas
paul.richard.thomas@gmail.com
Wed Feb 4 14:30:00 GMT 2015
Dear All,
Please find attached a reworked version of the patch for this PR. I
have no idea at all, why the original version worked for array
components on my laptop. In this version, the treatment of scalar and
array components is cleanly separated.
Bootstrapped and regtested on FC21/x86_64. OK for trunk?
Paul
2015-02-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/640757
* resolve.c (resolve_structure_cons): Obtain the rank of class
components.
* trans-expr.c (gfc_trans_alloc_subarray_assign): Do the
assignment to allocatable class array components.
(alloc_scalar_allocatable_for_subcomponent_assignment): If comp
is a class component, allocate to the _data field.
(gfc_trans_subcomponent_assign): If a class component with a
derived type expression set the _vptr field and for array
components, call gfc_trans_alloc_subarray_assign. For scalars,
the assignment is performed here.
2015-02-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/640757
* gfortran.dg/type_to_class_2.f90: New test
* gfortran.dg/type_to_class_3.f90: New test
On 3 February 2015 at 22:36, Paul Richard Thomas
<paul.richard.thomas@gmail.com> wrote:
> Dear Dominique,
>
> I have fixed all the problems except the last one. For that case, the
> other brand gives
> type_to_class_30.f90(19): error #7822: Variables containing ultimate
> allocatable array components are forbidden from appearing directly in
> input/output lists.
> print *, TestReference([Test(99), Test(199)])
> ---------^
> compilation aborted for type_to_class_30.f90 (code 1)
>
> which seems to me to be correct. I'll see what I can do to fix it.
>
> Thanks for the help
>
> Paul
>
> On 2 February 2015 at 17:53, Dominique Dhumieres <dominiq@lps.ens.fr> wrote:
>> Dear Paul,
>>
>> I have tested your patch at https://gcc.gnu.org/ml/fortran/2015-01/txtwnaoa1115V.txt
>> (the latest version) and I found that the test type_to_class_3.f03 is miscompiled
>> (FAIL) with -flto -O0 -m64 (this does not happens with -flto -O0 -m32 or with -Ox and
>> x!=0).
>>
>> In addition, while the reduced test
>>
>> type :: Test
>> integer :: i
>> end type
>>
>> type :: TestReference
>> class(Test), allocatable :: test(:)
>> end type
>>
>> type(TestReference) :: testList
>> type(test), allocatable :: x(:)
>>
>> allocate (testList%test(2), source = [Test(99), Test(199)]) ! Works, of course
>> print *, size(testList%test)
>> x = testList%test
>> print *, x
>> end
>>
>> gives what I expect, i.e.,
>>
>> 2
>> 99 199
>>
>> type :: Test
>> integer :: i
>> end type
>>
>> type :: TestReference
>> class(Test), allocatable :: test(:)
>> end type
>>
>> type(TestReference) :: testList
>> type(test), allocatable :: x(:)
>>
>> testList = TestReference([Test(99), Test(199)]) ! Gave: The rank of the element in the
>> ! structure constructor at (1) does not
>> ! match that of the component (1/0)
>> print *, size(testList%test)
>> x = testList%test
>> print *, x
>> end
>>
>> gives
>>
>> 1
>> 99
>>
>> Last problem I see,
>>
>> print *, TestReference([Test(99), Test(199)])
>>
>> gives the following ICE
>>
>> f951: internal compiler error: Bad IO basetype (7)
>>
>> type_to_class_3_red_2.f03:12:0:
>>
>> print *, TestReference([Test(99), Test(199)])
>>
>>
>> Cheers,
>>
>> Dominique
>
>
>
> --
> Outside of a dog, a book is a man's best friend. Inside of a dog it's
> too dark to read.
>
> Groucho Marx
--
Outside of a dog, a book is a man's best friend. Inside of a dog it's
too dark to read.
Groucho Marx
-------------- next part --------------
Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c (revision 220305)
--- gcc/fortran/resolve.c (working copy)
*************** resolve_structure_cons (gfc_expr *expr,
*** 1155,1160 ****
--- 1155,1163 ----
}
rank = comp->as ? comp->as->rank : 0;
+ if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->as)
+ rank = CLASS_DATA (comp)->as->rank;
+
if (cons->expr->expr_type != EXPR_NULL && rank != cons->expr->rank
&& (comp->attr.allocatable || cons->expr->rank))
{
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c (revision 220305)
--- gcc/fortran/trans-expr.c (working copy)
*************** gfc_trans_alloc_subarray_assign (tree de
*** 6211,6216 ****
--- 6211,6230 ----
tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
se.expr, dest,
cm->as->rank);
+ else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
+ && CLASS_DATA(cm)->attr.allocatable)
+ {
+ if (cm->ts.u.derived->attr.alloc_comp)
+ tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
+ se.expr, dest,
+ expr->rank);
+ else
+ {
+ tmp = TREE_TYPE (dest);
+ tmp = gfc_duplicate_allocatable (dest, se.expr,
+ tmp, expr->rank);
+ }
+ }
else
tmp = gfc_duplicate_allocatable (dest, se.expr,
TREE_TYPE(cm->backend_decl),
*************** alloc_scalar_allocatable_for_subcomponen
*** 6335,6340 ****
--- 6349,6355 ----
gfc_symbol *sym)
{
tree tmp;
+ tree ptr;
tree size;
tree size_in_bytes;
tree lhs_cl_size = NULL_TREE;
*************** alloc_scalar_allocatable_for_subcomponen
*** 6400,6407 ****
tmp = build_call_expr_loc (input_location,
builtin_decl_explicit (BUILT_IN_MALLOC),
1, size_in_bytes);
! tmp = fold_convert (TREE_TYPE (comp), tmp);
! gfc_add_modify (block, comp, tmp);
}
if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
--- 6415,6426 ----
tmp = build_call_expr_loc (input_location,
builtin_decl_explicit (BUILT_IN_MALLOC),
1, size_in_bytes);
! if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
! ptr = gfc_class_data_get (comp);
! else
! ptr = comp;
! tmp = fold_convert (TREE_TYPE (ptr), tmp);
! gfc_add_modify (block, ptr, tmp);
}
if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
*************** gfc_trans_subcomponent_assign (tree dest
*** 6420,6425 ****
--- 6439,6445 ----
gfc_se lse;
stmtblock_t block;
tree tmp;
+ tree vtab;
gfc_start_block (&block);
*************** gfc_trans_subcomponent_assign (tree dest
*** 6483,6488 ****
--- 6503,6522 ----
gfc_add_expr_to_block (&block, tmp);
}
}
+ else if (cm->ts.type == BT_CLASS
+ && CLASS_DATA (cm)->attr.dimension
+ && CLASS_DATA (cm)->attr.allocatable
+ && expr->ts.type == BT_DERIVED)
+ {
+ vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
+ vtab = gfc_build_addr_expr (NULL_TREE, vtab);
+ tmp = gfc_class_vptr_get (dest);
+ gfc_add_modify (&block, tmp,
+ fold_convert (TREE_TYPE (tmp), vtab));
+ tmp = gfc_class_data_get (dest);
+ tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
+ gfc_add_expr_to_block (&block, tmp);
+ }
else if (init && (cm->attr.allocatable
|| (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable)))
{
*************** gfc_trans_subcomponent_assign (tree dest
*** 6504,6510 ****
if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
&& expr->symtree->n.sym->attr.dummy)
se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
! tmp = build_fold_indirect_ref_loc (input_location, dest);
/* For deferred strings insert a memcpy. */
if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
{
--- 6538,6556 ----
if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
&& expr->symtree->n.sym->attr.dummy)
se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
!
! if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
! {
! tmp = gfc_class_data_get (dest);
! tmp = build_fold_indirect_ref_loc (input_location, tmp);
! vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
! vtab = gfc_build_addr_expr (NULL_TREE, vtab);
! gfc_add_modify (&block, gfc_class_vptr_get (dest),
! fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
! }
! else
! tmp = build_fold_indirect_ref_loc (input_location, dest);
!
/* For deferred strings insert a memcpy. */
if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
{
Index: gcc/testsuite/gfortran.dg/type_to_class_2.f03
===================================================================
*** gcc/testsuite/gfortran.dg/type_to_class_2.f03 (revision 0)
--- gcc/testsuite/gfortran.dg/type_to_class_2.f03 (working copy)
***************
*** 0 ****
--- 1,30 ----
+ ! { dg-do run }
+ !
+ ! Test the fix for PR64757.
+ !
+ ! Contributed by Michael Lee Rilee <mike@rilee.net>
+ !
+ type :: Test
+ integer :: i
+ end type
+
+ type :: TestReference
+ class(Test), allocatable :: test
+ end type
+
+ type(TestReference) :: testList
+ type(test) :: x
+
+ testList = TestReference(Test(99)) ! ICE in fold_convert_loc was here
+
+ x = testList%test
+
+ select type (y => testList%test) ! Check vptr set
+ type is (Test)
+ if (x%i .ne. y%i) call abort
+ class default
+ call abort
+ end select
+ end
+
+
Index: gcc/testsuite/gfortran.dg/type_to_class_3.f03
===================================================================
*** gcc/testsuite/gfortran.dg/type_to_class_3.f03 (revision 0)
--- gcc/testsuite/gfortran.dg/type_to_class_3.f03 (working copy)
***************
*** 0 ****
--- 1,33 ----
+ ! { dg-do run }
+ !
+ ! Test the fix for the array version of PR64757.
+ !
+ ! Based on by Michael Lee Rilee <mike@rilee.net>
+ !
+ type :: Test
+ integer :: i
+ end type
+
+ type :: TestReference
+ class(Test), allocatable :: test(:)
+ end type
+
+ type(TestReference) :: testList
+ type(test), allocatable :: x(:)
+
+ testList = TestReference([Test(99), Test(199)]) ! Gave: The rank of the element in the
+ ! structure constructor at (1) does not
+ ! match that of the component (1/0)
+ ! allocate (testList%test(2), source = [Test(99), Test(199)]) ! Works, of course
+
+ x = testList%test
+
+ select type (y => testList%test) ! Check vptr set
+ type is (Test)
+ if (any(x%i .ne. y%i)) call abort
+ class default
+ call abort
+ end select
+ end
+
+
More information about the Fortran
mailing list