summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authorvehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-24 10:28:48 +0000
committervehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-24 10:28:48 +0000
commit535b04841ef2bdba3c49001d099b0e4382f89aba (patch)
tree4cda0798b6bf5a397dc8dfb57c00dd489206a269 /gcc/fortran/trans-array.c
parentfe46ea6f8156a2818505505c25030f5d842ea38e (diff)
gcc/fortran/ChangeLog
2015-03-24 Andre Vehreschild <vehre@gmx.de> PR fortran/64787 PR fortran/57456 PR fortran/63230 * class.c (gfc_add_component_ref): Free no longer needed ref-chains to prevent memory loss. (find_intrinsic_vtab): For deferred length char arrays or unlimited polymorphic objects, store the size in bytes of one character in the size component of the vtab. * gfortran.h: Added gfc_add_len_component () define. * trans-array.c (gfc_trans_create_temp_array): Switched to new function name for getting a class' vtab's field. (build_class_array_ref): Likewise. (gfc_array_init_size): Using the size information from allocate more consequently now, i.e., the typespec of the entity to allocate is no longer needed. This is to address the last open comment in PR fortran/57456. (gfc_array_allocate): Likewise. (structure_alloc_comps): gfc_copy_class_to_class () needs to know whether the class is unlimited polymorphic. * trans-array.h: Changed interface of gfc_array_allocate () to reflect the no longer needed typespec. * trans-expr.c (gfc_find_and_cut_at_last_class_ref): New. (gfc_reset_len): New. (gfc_get_class_array_ref): Switch to new function name for getting a class' vtab's field. (gfc_copy_class_to_class): Added flag to know whether the class to copy is unlimited polymorphic. Adding _len dependent code then, which calls ->vptr->copy () with four arguments adding the length information ->vptr->copy(from, to, from_len, to_cap). (gfc_conv_procedure_call): Switch to new function name for getting a class' vtab's field. (alloc_scalar_allocatable_for_assignment): Use the string_length as computed by gfc_conv_expr and not the statically backend_decl which may be incorrect when ref-ing. (gfc_trans_assignment_1): Use the string_length variable and not the rse.string_length. The former has been computed more generally. * trans-intrinsic.c (gfc_conv_intrinsic_sizeof): Switch to new function name for getting a class' vtab's field. (gfc_conv_intrinsic_storage_size): Likewise. (gfc_conv_intrinsic_transfer): Likewise. * trans-stmt.c (gfc_trans_allocate): Restructured to evaluate source=expr3 only once before the loop over the objects to allocate, when the objects are not arrays. Doing correct _len initialization and calling of vptr->copy () fixing PR 64787. (gfc_trans_deallocate): Reseting _len to 0, preventing future errors. * trans.c (gfc_build_array_ref): Switch to new function name for getting a class' vtab's field. (gfc_add_comp_finalizer_call): Likewise. * trans.h: Define the prototypes for the gfc_class_vtab_*_get () and gfc_vptr_*_get () functions. Added gfc_find_and_cut_at_last_class_ref () and gfc_reset_len () routine prototype. Added flag to gfc_copy_class_to_class () prototype to signal an unlimited polymorphic entity to copy. gcc/testsuite/ChangeLog 2015-03-24 Andre Vehreschild <vehre@gmx.de> * gfortran.dg/allocate_alloc_opt_13.f90: Added tests for source= and mold= expressions functionality. * gfortran.dg/allocate_class_4.f90: New test. * gfortran.dg/unlimited_polymorphic_20.f90: Added test whether copying an unlimited polymorhpic object containing a char array to another unlimited polymorphic object respects the _len component. * gfortran.dg/unlimited_polymorphic_22.f90: Extended to check whether deferred length char array allocate works, unlimited polymorphic object allocation from a string works and if allocating an array of deferred length strings works. * gfortran.dg/unlimited_polymorphic_24.f03: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r--gcc/fortran/trans-array.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 0dbfdaab1b22..17689748eafa 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1196,7 +1196,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
elemsize = fold_convert (gfc_array_index_type,
TYPE_SIZE_UNIT (gfc_get_element_type (type)));
else
- elemsize = gfc_vtable_size_get (class_expr);
+ elemsize = gfc_class_vtab_size_get (class_expr);
size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
size, elemsize);
@@ -3066,7 +3066,7 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
if (!GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
return false;
- size = gfc_vtable_size_get (decl);
+ size = gfc_class_vtab_size_get (decl);
/* Build the address of the element. */
type = TREE_TYPE (TREE_TYPE (base));
@@ -4956,8 +4956,7 @@ static tree
gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
stmtblock_t * descriptor_block, tree * overflow,
- tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
- gfc_typespec *ts)
+ tree expr3_elem_size, tree *nelems, gfc_expr *expr3)
{
tree type;
tree tmp;
@@ -4983,7 +4982,7 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
/* Set the dtype. */
tmp = gfc_conv_descriptor_dtype (descriptor);
- gfc_add_modify (descriptor_block, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
+ gfc_add_modify (descriptor_block, tmp, gfc_get_dtype (type));
or_expr = boolean_false_node;
@@ -5137,9 +5136,6 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
tmp = TYPE_SIZE_UNIT (tmp);
}
}
- else if (ts->type != BT_UNKNOWN && ts->type != BT_CHARACTER)
- /* FIXME: Properly handle characters. See PR 57456. */
- tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (ts));
else
tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
@@ -5211,7 +5207,7 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
bool
gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
tree errlen, tree label_finish, tree expr3_elem_size,
- tree *nelems, gfc_expr *expr3, gfc_typespec *ts)
+ tree *nelems, gfc_expr *expr3)
{
tree tmp;
tree pointer;
@@ -5296,7 +5292,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
ref->u.ar.as->corank, &offset, lower, upper,
&se->pre, &set_descriptor_block, &overflow,
- expr3_elem_size, nelems, expr3, ts);
+ expr3_elem_size, nelems, expr3);
if (dimension)
{
@@ -7942,7 +7938,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
dst_data = gfc_class_data_get (dcmp);
src_data = gfc_class_data_get (comp);
- size = fold_convert (size_type_node, gfc_vtable_size_get (comp));
+ size = fold_convert (size_type_node,
+ gfc_class_vtab_size_get (comp));
if (CLASS_DATA (c)->attr.dimension)
{
@@ -7977,7 +7974,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
fold_convert (TREE_TYPE (dst_data), tmp));
}
- tmp = gfc_copy_class_to_class (comp, dcmp, nelems);
+ tmp = gfc_copy_class_to_class (comp, dcmp, nelems,
+ UNLIMITED_POLY (c));
gfc_add_expr_to_block (&tmpblock, tmp);
tmp = gfc_finish_block (&tmpblock);