aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2008-11-24 06:34:16 +0000
committerPaul Thomas <pault@gcc.gnu.org>2008-11-24 06:34:16 +0000
commit2c69d5275c7efc88be6791d2b3091a18082df7b9 (patch)
tree997d7059d19cf99dc2c6500197c911b74e98bef1 /gcc/fortran/trans-expr.c
parente4b9521065765f5ec954d0772a877bd9957478e3 (diff)
downloadgcc-2c69d5275c7efc88be6791d2b3091a18082df7b9.zip
gcc-2c69d5275c7efc88be6791d2b3091a18082df7b9.tar.gz
gcc-2c69d5275c7efc88be6791d2b3091a18082df7b9.tar.bz2
re PR fortran/34820 (internal compiler error: in gfc_conv_descriptor_data_get, at fortran/trans-array.c:147)
2008-11-24 Paul Thomas <pault@gcc.gnu.org> PR fortran/34820 * trans-expr.c (gfc_conv_function_call): Remove all code to deallocate intent out derived types with allocatable components. (gfc_trans_assignment_1): An assignment from a scalar to an array of derived types with allocatable components, requires a deep copy to each array element and deallocation of the converted rhs expression afterwards. * trans-array.c : Minor whitespace. * trans-decl.c (init_intent_out_dt): Add code to deallocate allocatable components of derived types with intent out. (generate_local_decl): If these types are unused, set them referenced anyway but allow the uninitialized warning. PR fortran/34143 * trans-expr.c (gfc_trans_subcomponent_assign): If a conversion expression has a null data pointer argument, nullify the allocatable component. PR fortran/32795 * trans-expr.c (gfc_trans_subcomponent_assign): Only nullify the data pointer if the source is not a variable. 2008-11-24 Paul Thomas <pault@gcc.gnu.org> PR fortran/34820 * gfortran.dg/alloc_comp_constructor_6.f90 : New test. * gfortran.dg/alloc_comp_basics_1.f90 : Reduce expected refs to 'builtin_free' from 24 to 18. PR fortran/34143 * gfortran.dg/alloc_comp_constructor_5.f90 : New test. PR fortran/32795 * gfortran.dg/alloc_comp_constructor_4.f90 : New test. From-SVN: r142148
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c79
1 files changed, 54 insertions, 25 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index e096021..5d3894c 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -2742,14 +2742,11 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
gfc_add_block_to_block (&post, &parmse.post);
/* Allocated allocatable components of derived types must be
- deallocated for INTENT(OUT) dummy arguments and non-variable
- scalars. Non-variable arrays are dealt with in trans-array.c
- (gfc_conv_array_parameter). */
+ deallocated for non-variable scalars. Non-variable arrays are
+ dealt with in trans-array.c(gfc_conv_array_parameter). */
if (e && e->ts.type == BT_DERIVED
&& e->ts.derived->attr.alloc_comp
- && ((formal && formal->sym->attr.intent == INTENT_OUT)
- ||
- (e->expr_type != EXPR_VARIABLE && !e->rank)))
+ && (e->expr_type != EXPR_VARIABLE && !e->rank))
{
int parm_rank;
tmp = build_fold_indirect_ref (parmse.expr);
@@ -2764,24 +2761,10 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
case (SCALAR_POINTER):
tmp = build_fold_indirect_ref (tmp);
break;
- case (ARRAY):
- tmp = parmse.expr;
- break;
}
- tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
- if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
- tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
- tmp, build_empty_stmt ());
-
- if (e->expr_type != EXPR_VARIABLE)
- /* Don't deallocate non-variables until they have been used. */
- gfc_add_expr_to_block (&se->post, tmp);
- else
- {
- gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
- gfc_add_expr_to_block (&se->pre, tmp);
- }
+ tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
+ gfc_add_expr_to_block (&se->post, tmp);
}
/* Character strings are passed as two parameters, a length and a
@@ -3610,9 +3593,10 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
cm->as->rank);
gfc_add_expr_to_block (&block, tmp);
-
gfc_add_block_to_block (&block, &se.post);
- gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
+
+ if (expr->expr_type != EXPR_VARIABLE)
+ gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
/* Shift the lbound and ubound of temporaries to being unity, rather
than zero, based. Calculate the offset for all cases. */
@@ -3644,6 +3628,35 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
gfc_add_modify (&block, offset, tmp);
}
+
+ if (expr->expr_type == EXPR_FUNCTION
+ && expr->value.function.isym
+ && expr->value.function.isym->conversion
+ && expr->value.function.actual->expr
+ && expr->value.function.actual->expr->expr_type
+ == EXPR_VARIABLE)
+ {
+ /* If a conversion expression has a null data pointer
+ argument, nullify the allocatable component. */
+ gfc_symbol *s;
+ tree non_null_expr;
+ tree null_expr;
+ s = expr->value.function.actual->expr->symtree->n.sym;
+ if (s->attr.allocatable || s->attr.pointer)
+ {
+ non_null_expr = gfc_finish_block (&block);
+ gfc_start_block (&block);
+ gfc_conv_descriptor_data_set (&block, dest,
+ null_pointer_node);
+ null_expr = gfc_finish_block (&block);
+ tmp = gfc_conv_descriptor_data_get (s->backend_decl);
+ tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
+ fold_convert (TREE_TYPE (tmp),
+ null_pointer_node));
+ return build3_v (COND_EXPR, tmp, null_expr,
+ non_null_expr);
+ }
+ }
}
else
{
@@ -4533,6 +4546,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
stmtblock_t block;
stmtblock_t body;
bool l_is_temp;
+ bool scalar_to_array;
/* Assignment of the form lhs = rhs. */
gfc_start_block (&block);
@@ -4616,9 +4630,24 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
else
gfc_conv_expr (&lse, expr1);
+ /* Assignments of scalar derived types with allocatable components
+ to arrays must be done with a deep copy and the rhs temporary
+ must have its components deallocated afterwards. */
+ scalar_to_array = (expr2->ts.type == BT_DERIVED
+ && expr2->ts.derived->attr.alloc_comp
+ && expr2->expr_type != EXPR_VARIABLE
+ && !gfc_is_constant_expr (expr2)
+ && expr1->rank && !expr2->rank);
+ if (scalar_to_array)
+ {
+ tmp = gfc_deallocate_alloc_comp (expr2->ts.derived, rse.expr, 0);
+ gfc_add_expr_to_block (&loop.post, tmp);
+ }
+
tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
l_is_temp || init_flag,
- expr2->expr_type == EXPR_VARIABLE);
+ (expr2->expr_type == EXPR_VARIABLE)
+ || scalar_to_array);
gfc_add_expr_to_block (&body, tmp);
if (lss == gfc_ss_terminator)