On 07/27/2011 09:58 AM, Tobias Burnus wrote:
Typo: desc(r)iptor_block.
Fixed.
You can combine changes different functions in a single file as in
* trans-openmp.c (gfc_omp_clause_default_ctor,
gfc_omp_clause_copy_ctor, gfc_trans_omp_array_reduction): ...
Fixed.
* gfortran.dg/multiple_allocation_3.f90: New test. Tests PR 49755.
The "Tests PR 49755." is redundant as one already has "PR fortran/49755".
Fixed.
Your patch does *not* compile for me as you missed to add gfc_likely to
trans.h:
gcc/fortran/trans-array.c:4554:4: error: 'gfc_likely' was not declared
in this scope
Fixed. It's very strange that the code compiles for me. I wonder why.
- ! This should set the stat code and change the size.
+ ! This should set the stat code but not change the size.
allocate(a(3),stat=i)
For later reference, I would prefer to add a comment stating that the
testcase has been modified to fix PR 49755. It's not really needed but
sometimes convenient to go back to all PRs which were involved in
creating/modifying the test case.
I have to make a new patch, so I might as well. New patch attached.
Otherwise, the patch is OK.
Great. I'm updating SVN, and after I check it compiles with the latest
trunk I'll commit.
Cheers,
Daniel.
--
I'm not overweight, I'm undertall.
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c (revision 176622)
+++ gcc/fortran/trans-array.c (working copy)
@@ -4146,3 +4146,3 @@ gfc_conv_descriptor_cosize (tree desc, i
a.stride[n] = stride;
- size = siz >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
+ size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
@@ -4164,4 +4164,4 @@ static tree
gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
- gfc_expr ** lower, gfc_expr ** upper,
- stmtblock_t * pblock, tree * overflow)
+ gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
+ stmtblock_t * descriptor_block, tree * overflow)
{
@@ -4191,3 +4191,3 @@ gfc_array_init_size (tree descriptor, in
tmp = gfc_conv_descriptor_dtype (descriptor);
- gfc_add_modify (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
+ gfc_add_modify (descriptor_block, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
@@ -4224,4 +4224,4 @@ gfc_array_init_size (tree descriptor, in
}
- gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
- se.expr);
+ gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
+ gfc_rank_cst[n], se.expr);
conv_lbound = se.expr;
@@ -4240,3 +4240,3 @@ gfc_array_init_size (tree descriptor, in
- gfc_conv_descriptor_ubound_set (pblock, descriptor,
+ gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
gfc_rank_cst[n], se.expr);
@@ -4245,3 +4245,3 @@ gfc_array_init_size (tree descriptor, in
/* Store the stride. */
- gfc_conv_descriptor_stride_set (pblock, descriptor,
+ gfc_conv_descriptor_stride_set (descriptor_block, descriptor,
gfc_rank_cst[n], stride);
@@ -4305,4 +4305,4 @@ gfc_array_init_size (tree descriptor, in
}
- gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
- se.expr);
+ gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
+ gfc_rank_cst[n], se.expr);
@@ -4314,3 +4314,3 @@ gfc_array_init_size (tree descriptor, in
gfc_add_block_to_block (pblock, &se.pre);
- gfc_conv_descriptor_ubound_set (pblock, descriptor,
+ gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
gfc_rank_cst[n], se.expr);
@@ -4397,2 +4397,4 @@ gfc_array_allocate (gfc_se * se, gfc_exp
tree cond;
+ tree set_descriptor;
+ stmtblock_t set_descriptor_block;
stmtblock_t elseblock;
@@ -4463,5 +4465,8 @@ gfc_array_allocate (gfc_se * se, gfc_exp
overflow = integer_zero_node;
+
+ gfc_init_block (&set_descriptor_block);
size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
ref->u.ar.as->corank, &offset, lower, upper,
- &se->pre, &overflow);
+ &se->pre, &set_descriptor_block, &overflow);
+
if (dimension)
@@ -4493,3 +4498,3 @@ gfc_array_allocate (gfc_se * se, gfc_exp
gfc_start_block (&elseblock);
-
+
/* Allocate memory to store the data. */
@@ -4500,11 +4505,6 @@ gfc_array_allocate (gfc_se * se, gfc_exp
if (allocatable)
- tmp = gfc_allocate_allocatable (&elseblock, pointer, size,
- status, errmsg, errlen, expr);
+ gfc_allocate_allocatable (&elseblock, pointer, size,
+ status, errmsg, errlen, expr);
else
- tmp = gfc_allocate_using_malloc (&elseblock, size, status);
-
- tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
- pointer, tmp);
-
- gfc_add_expr_to_block (&elseblock, tmp);
+ gfc_allocate_using_malloc (&elseblock, pointer, size, status);
@@ -4522,4 +4522,19 @@ gfc_array_allocate (gfc_se * se, gfc_exp
+ /* Update the array descriptors. */
if (dimension)
- gfc_conv_descriptor_offset_set (&se->pre, se->expr, offset);
+ gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
+
+ set_descriptor = gfc_finish_block (&set_descriptor_block);
+ if (status != NULL_TREE)
+ {
+ cond = fold_build2_loc (input_location, EQ_EXPR,
+ boolean_type_node, status,
+ build_int_cst (TREE_TYPE (status), 0));
+ gfc_add_expr_to_block (&se->pre,
+ fold_build3_loc (input_location, COND_EXPR, void_type_node,
+ gfc_likely (cond), set_descriptor,
+ build_empty_stmt (input_location)));
+ }
+ else
+ gfc_add_expr_to_block (&se->pre, set_descriptor);
Index: gcc/fortran/trans-openmp.c
===================================================================
--- gcc/fortran/trans-openmp.c (revision 176622)
+++ gcc/fortran/trans-openmp.c (working copy)
@@ -190,6 +190,7 @@ gfc_omp_clause_default_ctor (tree clause
size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
- ptr = gfc_allocate_allocatable (&cond_block,
- build_int_cst (pvoid_type_node, 0),
- size, NULL_TREE, NULL_TREE, NULL_TREE, NULL);
+
+ ptr = gfc_create_var (pvoid_type_node, NULL);
+ gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
+
then_b = gfc_finish_block (&cond_block);
@@ -243,6 +244,7 @@ gfc_omp_clause_copy_ctor (tree clause, t
size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
- ptr = gfc_allocate_allocatable (&block,
- build_int_cst (pvoid_type_node, 0),
- size, NULL_TREE, NULL_TREE, NULL_TREE, NULL);
+
+ ptr = gfc_create_var (pvoid_type_node, NULL);
+ gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
gfc_conv_descriptor_data_set (&block, dest, ptr);
+
call = build_call_expr_loc (input_location,
@@ -665,6 +667,7 @@ gfc_trans_omp_array_reduction (tree c, g
size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
- ptr = gfc_allocate_allocatable (&block,
- build_int_cst (pvoid_type_node, 0),
- size, NULL_TREE, NULL_TREE, NULL_TREE, NULL);
+
+ ptr = gfc_create_var (pvoid_type_node, NULL);
+ gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
gfc_conv_descriptor_data_set (&block, decl, ptr);
+
gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false,
Index: gcc/fortran/trans-stmt.c
===================================================================
--- gcc/fortran/trans-stmt.c (revision 176622)
+++ gcc/fortran/trans-stmt.c (working copy)
@@ -4869,11 +4869,6 @@ gfc_trans_allocate (gfc_code * code)
if (gfc_expr_attr (expr).allocatable)
- tmp = gfc_allocate_allocatable (&se.pre, se.expr, memsz,
- stat, errmsg, errlen, expr);
+ gfc_allocate_allocatable (&se.pre, se.expr, memsz,
+ stat, errmsg, errlen, expr);
else
- tmp = gfc_allocate_using_malloc (&se.pre, memsz, stat);
-
- tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
- se.expr,
- fold_convert (TREE_TYPE (se.expr), tmp));
- gfc_add_expr_to_block (&se.pre, tmp);
+ gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
@@ -4903,3 +4898,3 @@ gfc_trans_allocate (gfc_code * code)
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
- parm, tmp,
+ gfc_unlikely(parm), tmp,
build_empty_stmt (input_location));
Index: gcc/fortran/trans.c
===================================================================
--- gcc/fortran/trans.c (revision 176622)
+++ gcc/fortran/trans.c (working copy)
@@ -584,7 +584,7 @@ gfc_call_malloc (stmtblock_t * block, tr
} */
-tree
-gfc_allocate_using_malloc (stmtblock_t * block, tree size, tree status)
+void
+gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
+ tree size, tree status)
{
- stmtblock_t alloc_block;
- tree res, tmp, on_error;
+ tree tmp, on_error, error_cond;
tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
@@ -596,6 +596,3 @@ gfc_allocate_using_malloc (stmtblock_t *
- /* Create a variable to hold the result. */
- res = gfc_create_var (prvoid_type_node, NULL);
-
- /* Set the optional status variable to zero. */
+ /* If successful and stat= is given, set status to 0. */
if (status != NULL_TREE)
@@ -606,5 +603,4 @@ gfc_allocate_using_malloc (stmtblock_t *
/* The allocation itself. */
- gfc_start_block (&alloc_block);
- gfc_add_modify (&alloc_block, res,
- fold_convert (prvoid_type_node,
+ gfc_add_modify (block, pointer,
+ fold_convert (TREE_TYPE (pointer),
build_call_expr_loc (input_location,
@@ -625,12 +621,10 @@ gfc_allocate_using_malloc (stmtblock_t *
+ error_cond = fold_build2_loc (input_location, EQ_EXPR,
+ boolean_type_node, pointer,
+ build_int_cst (prvoid_type_node, 0));
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
- fold_build2_loc (input_location, EQ_EXPR,
- boolean_type_node, res,
- build_int_cst (prvoid_type_node, 0)),
- on_error, build_empty_stmt (input_location));
+ gfc_unlikely(error_cond), on_error,
+ build_empty_stmt (input_location));
- gfc_add_expr_to_block (&alloc_block, tmp);
- gfc_add_expr_to_block (block, gfc_finish_block (&alloc_block));
-
- return res;
+ gfc_add_expr_to_block (block, tmp);
}
@@ -650,7 +644,7 @@ gfc_allocate_using_malloc (stmtblock_t *
} */
-tree
-gfc_allocate_using_lib (stmtblock_t * block, tree size, tree status,
- tree errmsg, tree errlen)
+void
+gfc_allocate_using_lib (stmtblock_t * block, tree pointer, tree size,
+ tree status, tree errmsg, tree errlen)
{
- tree res, pstat;
+ tree tmp, pstat;
@@ -661,5 +655,2 @@ gfc_allocate_using_lib (stmtblock_t * bl
- /* Create a variable to hold the result. */
- res = gfc_create_var (prvoid_type_node, NULL);
-
/* The allocation itself. */
@@ -677,15 +668,16 @@ gfc_allocate_using_lib (stmtblock_t * bl
- gfc_add_modify (block, res,
- fold_convert (prvoid_type_node,
- build_call_expr_loc (input_location,
- gfor_fndecl_caf_register, 6,
- fold_build2_loc (input_location,
+ tmp = build_call_expr_loc (input_location,
+ gfor_fndecl_caf_register, 6,
+ fold_build2_loc (input_location,
MAX_EXPR, size_type_node, size,
build_int_cst (size_type_node, 1)),
- build_int_cst (integer_type_node,
+ build_int_cst (integer_type_node,
GFC_CAF_COARRAY_ALLOC),
- null_pointer_node, /* token */
- pstat, errmsg, errlen)));
+ null_pointer_node, /* token */
+ pstat, errmsg, errlen);
- return res;
+ tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+ TREE_TYPE (pointer), pointer,
+ fold_convert ( TREE_TYPE (pointer), tmp));
+ gfc_add_expr_to_block (block, tmp);
}
@@ -707,8 +699,3 @@ gfc_allocate_using_lib (stmtblock_t * bl
if (stat)
- {
- free (mem);
- mem = allocate (size, stat);
stat = LIBERROR_ALLOCATION;
- return mem;
- }
else
@@ -720,3 +707,3 @@ gfc_allocate_using_lib (stmtblock_t * bl
and variable name in case a runtime error has to be printed. */
-tree
+void
gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree status,
@@ -725,3 +712,3 @@ gfc_allocate_allocatable (stmtblock_t *
stmtblock_t alloc_block;
- tree res, tmp, null_mem, alloc, error;
+ tree tmp, null_mem, alloc, error;
tree type = TREE_TYPE (mem);
@@ -731,4 +718,2 @@ gfc_allocate_allocatable (stmtblock_t *
- /* Create a variable to hold the result. */
- res = gfc_create_var (type, NULL);
null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
@@ -743,8 +728,7 @@ gfc_allocate_allocatable (stmtblock_t *
&& gfc_expr_attr (expr).codimension)
- tmp = gfc_allocate_using_lib (&alloc_block, size, status,
- errmsg, errlen);
+ gfc_allocate_using_lib (&alloc_block, mem, size, status,
+ errmsg, errlen);
else
- tmp = gfc_allocate_using_malloc (&alloc_block, size, status);
+ gfc_allocate_using_malloc (&alloc_block, mem, size, status);
- gfc_add_modify (&alloc_block, res, fold_convert (type, tmp));
alloc = gfc_finish_block (&alloc_block);
@@ -774,16 +758,5 @@ gfc_allocate_allocatable (stmtblock_t *
tree status_type = TREE_TYPE (status);
- stmtblock_t set_status_block;
- gfc_start_block (&set_status_block);
- tmp = build_call_expr_loc (input_location,
- built_in_decls[BUILT_IN_FREE], 1,
- fold_convert (pvoid_type_node, mem));
- gfc_add_expr_to_block (&set_status_block, tmp);
-
- tmp = gfc_allocate_using_malloc (&set_status_block, size, status);
- gfc_add_modify (&set_status_block, res, fold_convert (type, tmp));
-
- gfc_add_modify (&set_status_block, status,
- build_int_cst (status_type, LIBERROR_ALLOCATION));
- error = gfc_finish_block (&set_status_block);
+ error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
+ status, build_int_cst (status_type, LIBERROR_ALLOCATION));
}
@@ -793,4 +766,2 @@ gfc_allocate_allocatable (stmtblock_t *
gfc_add_expr_to_block (block, tmp);
-
- return res;
}
@@ -1621,1 +1592,17 @@ gfc_unlikely (tree cond)
}
+
+
+/* Helper function for marking a boolean expression tree as likely. */
+
+tree
+gfc_likely (tree cond)
+{
+ tree tmp;
+
+ cond = fold_convert (long_integer_type_node, cond);
+ tmp = build_one_cst (long_integer_type_node);
+ cond = build_call_expr_loc (input_location,
+ built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
+ cond = fold_convert (boolean_type_node, cond);
+ return cond;
+}
Index: gcc/fortran/trans.h
===================================================================
--- gcc/fortran/trans.h (revision 176622)
+++ gcc/fortran/trans.h (working copy)
@@ -519,3 +519,4 @@ bool get_array_ctor_strlen (stmtblock_t
-/* Mark a condition as unlikely. */
+/* Mark a condition as likely or unlikely. */
+tree gfc_likely (tree);
tree gfc_unlikely (tree);
@@ -543,3 +544,3 @@ tree gfc_build_memcpy_call (tree, tree,
/* Allocate memory for allocatable variables, with optional status variable. */
-tree gfc_allocate_allocatable (stmtblock_t*, tree, tree,
+void gfc_allocate_allocatable (stmtblock_t*, tree, tree,
tree, tree, tree, gfc_expr*);
@@ -547,4 +548,4 @@ tree gfc_allocate_allocatable (stmtblock
/* Allocate memory, with optional status variable. */
-tree gfc_allocate_using_malloc (stmtblock_t *, tree, tree);
-tree gfc_allocate_using_lib (stmtblock_t *, tree, tree, tree, tree);
+void gfc_allocate_using_malloc (stmtblock_t *, tree, tree, tree);
+void gfc_allocate_using_lib (stmtblock_t *, tree, tree, tree, tree, tree);
Index: gcc/testsuite/gfortran.dg/multiple_allocation_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/multiple_allocation_1.f90 (revision 176622)
+++ gcc/testsuite/gfortran.dg/multiple_allocation_1.f90 (working copy)
@@ -3,2 +3,4 @@
! allocated array.
+!
+! This testcase has been modified to fix PR 49755.
program alloc_test
@@ -10,3 +12,3 @@ program alloc_test
allocate(a(4))
- ! This should set the stat code and change the size.
+ ! This should set the stat code but not change the size.
allocate(a(3),stat=i)
@@ -14,3 +16,4 @@ program alloc_test
if (.not. allocated(a)) call abort
- if (size(a) /= 3) call abort
+ if (size(a) /= 4) call abort
+
! It's OK to allocate pointers twice (even though this causes