This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch,Fortran] PRs 45451 / 43018: Fixes for allocatables
- From: Tobias Burnus <burnus at net-b dot de>
- To: gcc patches <gcc-patches at gcc dot gnu dot org>, gfortran <fortran at gcc dot gnu dot org>
- Date: Tue, 26 Oct 2010 00:24:00 +0200
- Subject: [Patch,Fortran] PRs 45451 / 43018: Fixes for allocatables
Hi,
this patch fixes two things:
a) PR 43018: For duplicate_allocatable the size was wrong: gfortran used
for scalars the size of the pointer and not the size of the type.
I have not added a test case as it was found via the valgrind error of
gfortran.de/alloc_comp_scalar_1.f90; the test case also fails one one
system (s390?).
b) PR 45451: If one does an ALLOCATE with SOURCE=, one needs to do a
deep copy if there are allocatable components.
Without the non-variable case, it fails for the first ALLOCATE statement
in gfortran.dg/allocate_alloc_opt_10.f90, where the source is an
EXPR_STRUCTURE.
Build an regtested on x86-64-linux.
OK for the trunk?
Tobias
PS: This patch does not fix all problems with PR 45451. It also does not
fix the case of a polymorphic SOURCE= with allocatable components (cf.
new PR 46174).
2010-10-25 Tobias Burnus <burnus@net-b.de>
PR fortran/45451
* trans-stmt.c (gfc_trans_allocate): Do a deep-copy for SOURCE=.
PR fortran/43018
* trans-array.c (duplicate_allocatable): Use size of type and not
the size of the pointer to the type.
2010-10-25 Tobias Burnus <burnus@net-b.de>gfortran.dg/class_allocate_5.f90
PR fortran/45451
* gfortran.dg/class_allocate_5.f90: New.
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 52ba831..db05734 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6072,7 +6072,7 @@ duplicate_allocatable (tree dest, tree src, tree type, int rank,
null_data = gfc_finish_block (&block);
gfc_init_block (&block);
- size = TYPE_SIZE_UNIT (type);
+ size = TYPE_SIZE_UNIT (TREE_TYPE (type));
if (!no_malloc)
{
tmp = gfc_call_malloc (&block, type, size);
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 6e1a20b..d079230 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -4487,8 +4487,12 @@ gfc_trans_allocate (gfc_code * code)
/* Initialization via SOURCE block
(or static default initializer). */
gfc_expr *rhs = gfc_copy_expr (code->expr3);
- if (al->expr->ts.type == BT_CLASS)
+ if (al->expr->ts.type == BT_CLASS && rhs->expr_type == EXPR_VARIABLE
+ && rhs->ts.type != BT_CLASS)
+ tmp = gfc_trans_assignment (expr, rhs, false, false);
+ else if (al->expr->ts.type == BT_CLASS)
{
+ /* TODO: One needs to do a deep-copy for BT_CLASS; cf. PR 46174. */
gfc_se dst,src;
if (rhs->ts.type == BT_CLASS)
gfc_add_component_ref (rhs, "$data");
diff --git a/gcc/testsuite/gfortran.dg/class_allocate_5.f90 b/gcc/testsuite/gfortran.dg/class_allocate_5.f90
new file mode 100644
index 0000000..592161e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_allocate_5.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+!
+! PR fortran/45451
+!
+! Contributed by Salvatore Filippone and Janus Weil
+!
+! Check that ALLOCATE with SOURCE= does a deep copy.
+!
+program bug23
+ implicit none
+
+ type :: psb_base_sparse_mat
+ integer, allocatable :: irp(:)
+ end type psb_base_sparse_mat
+
+ class(psb_base_sparse_mat), allocatable :: a
+ type(psb_base_sparse_mat) :: acsr
+
+ allocate(acsr%irp(4))
+ acsr%irp(1:4) = (/1,3,4,5/)
+
+ write(*,*) acsr%irp(:)
+
+ allocate(a,source=acsr)
+
+ write(*,*) a%irp(:)
+
+ call move_alloc(acsr%irp, a%irp)
+
+ write(*,*) a%irp(:)
+
+ if (any (a%irp /= [1,3,4,5])) call abort()
+end program bug23
+