re PR fortran/64578 ([OOP] Seg-fault and ICE with unlimited polymorphic array pointer function)
2015-01-18 Paul Thomas <pault@gcc.gnu.org> PR fortran/64578 * trans-expr.c (gfc_trans_subcomponent_assign): Use a deep copy for allocatable components, where the source is a variable. 2015-01-18 Paul Thomas <pault@gcc.gnu.org> PR fortran/64578 * gfortran.dg/block_13.f08: New test From-SVN: r219818
This commit is contained in:
parent
fded3d73da
commit
a878f8e80c
4 changed files with 79 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
2015-01-18 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/64578
|
||||
* trans-expr.c (gfc_trans_subcomponent_assign): Use a deep copy
|
||||
for allocatable components, where the source is a variable.
|
||||
|
||||
2015-01-18 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/55901
|
||||
|
|
|
@ -6474,8 +6474,16 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
|
|||
gfc_init_se (&se, NULL);
|
||||
gfc_conv_expr (&se, expr);
|
||||
gfc_add_block_to_block (&block, &se.pre);
|
||||
gfc_add_modify (&block, dest,
|
||||
fold_convert (TREE_TYPE (dest), se.expr));
|
||||
if (cm->ts.u.derived->attr.alloc_comp
|
||||
&& expr->expr_type == EXPR_VARIABLE)
|
||||
{
|
||||
tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
|
||||
dest, expr->rank);
|
||||
gfc_add_expr_to_block (&block, tmp);
|
||||
}
|
||||
else
|
||||
gfc_add_modify (&block, dest,
|
||||
fold_convert (TREE_TYPE (dest), se.expr));
|
||||
gfc_add_block_to_block (&block, &se.post);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2015-01-18 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/64578
|
||||
* gfortran.dg/block_13.f08: New test
|
||||
|
||||
2015-01-18 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/55901
|
||||
|
|
58
gcc/testsuite/gfortran.dg/block_13.f08
Normal file
58
gcc/testsuite/gfortran.dg/block_13.f08
Normal file
|
@ -0,0 +1,58 @@
|
|||
! { dg-do run }
|
||||
! Checks the fix for PR57959. The first assignment to a was proceeding
|
||||
! without a deep copy. Since the anum field of 'uKnot' was being pointed
|
||||
! to twice, the frees in the finally block, following the BLOCK caused
|
||||
! a double free.
|
||||
!
|
||||
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
|
||||
!
|
||||
program main
|
||||
implicit none
|
||||
type :: type1
|
||||
real, allocatable :: anum
|
||||
character(len = :), allocatable :: chr
|
||||
end type type1
|
||||
real, parameter :: five = 5.0
|
||||
real, parameter :: point_one = 0.1
|
||||
|
||||
type :: type2
|
||||
type(type1) :: temp
|
||||
end type type2
|
||||
block
|
||||
type(type1) :: uKnot
|
||||
type(type2) :: a
|
||||
|
||||
uKnot = type1 (five, "hello")
|
||||
call check (uKnot%anum, five)
|
||||
call check_chr (uKnot%chr, "hello")
|
||||
|
||||
a = type2 (uKnot) ! Deep copy needed here
|
||||
call check (a%temp%anum, five)
|
||||
call check_chr (a%temp%chr, "hello")
|
||||
|
||||
a = type2 (type1(point_one, "goodbye")) ! Not here
|
||||
call check (a%temp%anum, point_one)
|
||||
call check_chr (a%temp%chr, "goodbye")
|
||||
|
||||
a = type2 (foo (five)) ! Not here
|
||||
call check (a%temp%anum, five)
|
||||
call check_chr (a%temp%chr, "foo set me")
|
||||
end block
|
||||
contains
|
||||
subroutine check (arg1, arg2)
|
||||
real :: arg1, arg2
|
||||
if (arg1 .ne. arg2) call abort ()
|
||||
end subroutine
|
||||
|
||||
subroutine check_chr (arg1, arg2)
|
||||
character(*) :: arg1, arg2
|
||||
if (len (arg1) .ne. len (arg2)) call abort
|
||||
if (arg1 .ne. arg2) call abort
|
||||
end subroutine
|
||||
|
||||
type(type1) function foo (arg)
|
||||
real :: arg
|
||||
foo = type1 (arg, "foo set me")
|
||||
end function
|
||||
end
|
||||
|
Loading…
Add table
Reference in a new issue