re PR fortran/50050 (Internal compiler error free_expr0 at expr.c:3709 via gfc_done_2)

2011-08-22  Mikael Morin  <mikael.morin@gcc.gnu.org>

	PR fortran/50050
	* gfortran.h (gfc_clear_shape, gfc_free_shape): New prototypes.
	* expr.c (gfc_clear_shape, gfc_free_shape): New functions.
	(free_expr0): Re-use gfc_free_shape.
	* trans-expr.c (gfc_trans_subarray_assign): Ditto.
	* trans-io.c (transfer_array_component): Ditto.
	* resolve.c (check_host_association): Ditto.
	(gfc_expr_to_initialize): Don't force the rank value and free the shape
	after updating the expression. Recalculate shape and rank.
	(resolve_where_shape): Re-use gfc_clear_shape.
	* array.c (gfc_array_ref_shape): Ditto.

2011-08-22  Mikael Morin  <mikael.morin@gcc.gnu.org>

	PR fortran/50050
	* gfortran.dg/alloc_comp_initializer_3.f90: New test.

From-SVN: r177956
This commit is contained in:
Mikael Morin 2011-08-22 14:07:30 +00:00
parent 977e83a3ed
commit 7d7212ec2b
9 changed files with 67 additions and 32 deletions

View File

@ -1,3 +1,17 @@
2011-08-22 Mikael Morin <mikael.morin@gcc.gnu.org>
PR fortran/50050
* gfortran.h (gfc_clear_shape, gfc_free_shape): New prototypes.
* expr.c (gfc_clear_shape, gfc_free_shape): New functions.
(free_expr0): Re-use gfc_free_shape.
* trans-expr.c (gfc_trans_subarray_assign): Ditto.
* trans-io.c (transfer_array_component): Ditto.
* resolve.c (check_host_association): Ditto.
(gfc_expr_to_initialize): Don't force the rank value and free the shape
after updating the expression. Recalculate shape and rank.
(resolve_where_shape): Re-use gfc_clear_shape.
* array.c (gfc_array_ref_shape): Ditto.
2011-08-21 Thomas Koenig <tkoenig@gcc.gnu.org> 2011-08-21 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/47659 PR fortran/47659
@ -18,7 +32,7 @@
* dependency.c (gfc_dep_compare_expr): Add new result value "-3". * dependency.c (gfc_dep_compare_expr): Add new result value "-3".
(gfc_check_element_vs_section,gfc_check_element_vs_element): Handle (gfc_check_element_vs_section,gfc_check_element_vs_element): Handle
result value "-3". result value "-3".
* frontend-passes.c (optimize_comparison): Ditto. * frontend-passes.c (optimize_comparison): Ditto.
* interface.c (gfc_check_typebound_override): Ditto. * interface.c (gfc_check_typebound_override): Ditto.
2011-08-19 Mikael Morin <mikael.morin@sfr.fr> 2011-08-19 Mikael Morin <mikael.morin@sfr.fr>

View File

@ -2281,9 +2281,7 @@ gfc_array_ref_shape (gfc_array_ref *ar, mpz_t *shape)
} }
cleanup: cleanup:
for (d--; d >= 0; d--) gfc_clear_shape (shape, d);
mpz_clear (shape[d]);
return FAILURE; return FAILURE;
} }

View File

@ -396,6 +396,25 @@ gfc_copy_expr (gfc_expr *p)
} }
void
gfc_clear_shape (mpz_t *shape, int rank)
{
int i;
for (i = 0; i < rank; i++)
mpz_clear (shape[i]);
}
void
gfc_free_shape (mpz_t **shape, int rank)
{
gfc_clear_shape (*shape, rank);
free (*shape);
*shape = NULL;
}
/* Workhorse function for gfc_free_expr() that frees everything /* Workhorse function for gfc_free_expr() that frees everything
beneath an expression node, but not the node itself. This is beneath an expression node, but not the node itself. This is
useful when we want to simplify a node and replace it with useful when we want to simplify a node and replace it with
@ -404,8 +423,6 @@ gfc_copy_expr (gfc_expr *p)
static void static void
free_expr0 (gfc_expr *e) free_expr0 (gfc_expr *e)
{ {
int n;
switch (e->expr_type) switch (e->expr_type)
{ {
case EXPR_CONSTANT: case EXPR_CONSTANT:
@ -474,12 +491,7 @@ free_expr0 (gfc_expr *e)
/* Free a shape array. */ /* Free a shape array. */
if (e->shape != NULL) if (e->shape != NULL)
{ gfc_free_shape (&e->shape, e->rank);
for (n = 0; n < e->rank; n++)
mpz_clear (e->shape[n]);
free (e->shape);
}
gfc_free_ref_list (e->ref); gfc_free_ref_list (e->ref);

View File

@ -2711,6 +2711,8 @@ gfc_expr *gfc_get_int_expr (int, locus *, int);
gfc_expr *gfc_get_logical_expr (int, locus *, bool); gfc_expr *gfc_get_logical_expr (int, locus *, bool);
gfc_expr *gfc_get_iokind_expr (locus *, io_kind); gfc_expr *gfc_get_iokind_expr (locus *, io_kind);
void gfc_clear_shape (mpz_t *shape, int rank);
void gfc_free_shape (mpz_t **shape, int rank);
void gfc_free_expr (gfc_expr *); void gfc_free_expr (gfc_expr *);
void gfc_replace_expr (gfc_expr *, gfc_expr *); void gfc_replace_expr (gfc_expr *, gfc_expr *);
mpz_t *gfc_copy_shape (mpz_t *, int); mpz_t *gfc_copy_shape (mpz_t *, int);

View File

@ -5199,12 +5199,7 @@ check_host_association (gfc_expr *e)
{ {
/* Clear the shape, since it might not be valid. */ /* Clear the shape, since it might not be valid. */
if (e->shape != NULL) if (e->shape != NULL)
{ gfc_free_shape (&e->shape, e->rank);
for (n = 0; n < e->rank; n++)
mpz_clear (e->shape[n]);
free (e->shape);
}
/* Give the expression the right symtree! */ /* Give the expression the right symtree! */
gfc_find_sym_tree (e->symtree->name, NULL, 1, &st); gfc_find_sym_tree (e->symtree->name, NULL, 1, &st);
@ -6559,10 +6554,13 @@ gfc_expr_to_initialize (gfc_expr *e)
for (i = 0; i < ref->u.ar.dimen; i++) for (i = 0; i < ref->u.ar.dimen; i++)
ref->u.ar.start[i] = ref->u.ar.end[i] = ref->u.ar.stride[i] = NULL; ref->u.ar.start[i] = ref->u.ar.end[i] = ref->u.ar.stride[i] = NULL;
result->rank = ref->u.ar.dimen;
break; break;
} }
gfc_free_shape (&result->shape, result->rank);
/* Recalculate rank, shape, etc. */
gfc_resolve_expr (result);
return result; return result;
} }
@ -8429,11 +8427,8 @@ ignore:
result = SUCCESS; result = SUCCESS;
over: over:
for (i--; i >= 0; i--) gfc_clear_shape (shape, i);
{ gfc_clear_shape (shape2, i);
mpz_clear (shape[i]);
mpz_clear (shape2[i]);
}
return result; return result;
} }

View File

@ -4411,10 +4411,7 @@ gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
gfc_add_block_to_block (&block, &loop.pre); gfc_add_block_to_block (&block, &loop.pre);
gfc_add_block_to_block (&block, &loop.post); gfc_add_block_to_block (&block, &loop.post);
for (n = 0; n < cm->as->rank; n++) gfc_free_shape (&lss->shape, cm->as->rank);
mpz_clear (lss->shape[n]);
free (lss->shape);
gfc_cleanup_loop (&loop); gfc_cleanup_loop (&loop);
return gfc_finish_block (&block); return gfc_finish_block (&block);

View File

@ -1999,10 +1999,7 @@ transfer_array_component (tree expr, gfc_component * cm, locus * where)
gfc_add_block_to_block (&block, &loop.pre); gfc_add_block_to_block (&block, &loop.pre);
gfc_add_block_to_block (&block, &loop.post); gfc_add_block_to_block (&block, &loop.post);
for (n = 0; n < cm->as->rank; n++) gfc_free_shape (&ss->shape, cm->as->rank);
mpz_clear (ss->shape[n]);
free (ss->shape);
gfc_cleanup_loop (&loop); gfc_cleanup_loop (&loop);
return gfc_finish_block (&block); return gfc_finish_block (&block);

View File

@ -1,3 +1,8 @@
2011-08-22 Mikael Morin <mikael.morin@gcc.gnu.org>
PR fortran/50050
* gfortran.dg/alloc_comp_initializer_3.f90: New test.
2011-08-22 Georg-Johann Lay <avr@gjlay.de> 2011-08-22 Georg-Johann Lay <avr@gjlay.de>
* gcc.dg/pr49994-2.c: Add dg-require-effective-target scheduling. * gcc.dg/pr49994-2.c: Add dg-require-effective-target scheduling.

View File

@ -0,0 +1,15 @@
! { dg-do compile }
!
! PR fortran/50050
! Out of bound whilst releasing initialization of allocate object
!
! Contributed by someone <sigurdkn@gmail.com>
program bug
implicit none
type foo
integer, pointer :: a => null()
end type
type(foo), dimension(:,:), allocatable :: data
allocate(data(1:1,1)) ! This used to lead to an ICE
end program