aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans.c
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gmx.de>2015-04-23 13:32:00 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2015-04-23 13:32:00 +0200
commitf3b0bb7a560be0f05b09287401a10c4c4b12cfc6 (patch)
tree59696dbb795a0a0b6ebd4e66730a0a3c2315c6d1 /gcc/fortran/trans.c
parenteff973a26bfec7032229170de11cbad63f4a2e64 (diff)
downloadgcc-f3b0bb7a560be0f05b09287401a10c4c4b12cfc6.zip
gcc-f3b0bb7a560be0f05b09287401a10c4c4b12cfc6.tar.gz
gcc-f3b0bb7a560be0f05b09287401a10c4c4b12cfc6.tar.bz2
PF fortran/60322
gcc/testsuite/ChangeLog: 2015-04-23 Andre Vehreschild <vehre@gmx.de> PF fortran/60322 * gfortran.dg/class_allocate_19.f03: New test. * gfortran.dg/class_array_20.f03: New test. * gfortran.dg/class_array_21.f03: New test. * gfortran.dg/finalize_10.f90: Corrected scan-trees. * gfortran.dg/finalize_15.f90: Fixing comparision to model initialization correctly. * gfortran.dg/finalize_29.f08: New test. gcc/fortran/ChangeLog: 2015-04-23 Andre Vehreschild <vehre@gmx.de> PR fortran/60322 * expr.c (gfc_lval_expr_from_sym): Code to select the regular or class array added. * gfortran.h: Add IS_CLASS_ARRAY macro. * trans-array.c (gfc_add_loop_ss_code): Treat class objects to be referenced always. (build_class_array_ref): Adapt retrieval of array descriptor. (build_array_ref): Likewise. (gfc_conv_array_ref): Hand the vptr or the descriptor to build_array_ref depending whether the sym is class or not. (gfc_trans_array_cobounds): Select correct gfc_array_spec for regular and class arrays. (gfc_trans_array_bounds): Likewise. (gfc_trans_dummy_array_bias): Likewise. (gfc_get_dataptr_offset): Correcting call of build_array_ref. (gfc_conv_expr_descriptor): Set the array's offset to -1 when lbound in inner most dim is 1 and symbol non-pointer/assoc. * trans-decl.c (gfc_build_qualified_array): Select correct gfc_array_spec for regular and class arrays. (gfc_build_dummy_array_decl): Likewise. (gfc_get_symbol_decl): Get a dummy array for class arrays. (gfc_trans_deferred_vars): Tell conv_expr that the descriptor is desired. * trans-expr.c (gfc_class_vptr_get): Get the class descriptor from the correct location for class arrays. (gfc_class_len_get): Likewise. (gfc_conv_intrinsic_to_class): Add handling of _len component. (gfc_conv_class_to_class): Prevent access to unset array data when the array is an optional argument. Add handling of _len component. (gfc_copy_class_to_class): Check that _def_init is non-NULL when used in _vptr->copy() (gfc_trans_class_init_assign): Ensure that the rank of _def_init is zero. (gfc_conv_component_ref): Get the _vptr along with _data refs. (gfc_conv_variable): Make sure the temp array descriptor is returned for class arrays, too, and that class arrays are dereferenced correctly. (gfc_conv_procedure_call): For polymorphic type initialization the initializer has to be a pointer to _def_init stored in a dummy variable, which then needs to be used by value. * trans-intrinsic.c (gfc_conv_intrinsic_sizeof): Use the temporary array descriptor for class arrays, too. (gfc_conv_intrinsic_storage_size): Likewise. (gfc_conv_intrinsic_loc): Add ref to _data for BT_CLASS expressions. * trans-stmt.c (trans_associate_var): Use a temporary array for the associate variable of class arrays, too, making the array one-based (lbound == 1). * trans-types.c (gfc_is_nodesc_array): Use the correct array data. * trans.c (gfc_build_array_ref): Use the dummy array descriptor when present. * trans.h: Add class_vptr to gfc_se for storing a class ref's vptr. From-SVN: r222361
Diffstat (limited to 'gcc/fortran/trans.c')
-rw-r--r--gcc/fortran/trans.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 549e921..2dabf08 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -321,7 +321,7 @@ gfc_build_addr_expr (tree type, tree t)
/* Build an ARRAY_REF with its natural type. */
tree
-gfc_build_array_ref (tree base, tree offset, tree decl)
+gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
{
tree type = TREE_TYPE (base);
tree tmp;
@@ -353,30 +353,47 @@ gfc_build_array_ref (tree base, tree offset, tree decl)
/* If the array reference is to a pointer, whose target contains a
subreference, use the span that is stored with the backend decl
and reference the element with pointer arithmetic. */
- if (decl && (TREE_CODE (decl) == FIELD_DECL
- || TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == PARM_DECL)
- && ((GFC_DECL_SUBREF_ARRAY_P (decl)
- && !integer_zerop (GFC_DECL_SPAN(decl)))
+ if ((decl && (TREE_CODE (decl) == FIELD_DECL
+ || TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == PARM_DECL)
+ && ((GFC_DECL_SUBREF_ARRAY_P (decl)
+ && !integer_zerop (GFC_DECL_SPAN (decl)))
|| GFC_DECL_CLASS (decl)))
+ || vptr)
{
- if (GFC_DECL_CLASS (decl))
+ if (decl)
{
- /* Allow for dummy arguments and other good things. */
- if (POINTER_TYPE_P (TREE_TYPE (decl)))
- decl = build_fold_indirect_ref_loc (input_location, decl);
-
- /* Check if '_data' is an array descriptor. If it is not,
- the array must be one of the components of the class object,
- so return a normal array reference. */
- if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_class_data_get (decl))))
- return build4_loc (input_location, ARRAY_REF, type, base,
- offset, NULL_TREE, NULL_TREE);
-
- span = gfc_class_vtab_size_get (decl);
+ if (GFC_DECL_CLASS (decl))
+ {
+ /* When a temporary is in place for the class array, then the
+ original class' declaration is stored in the saved
+ descriptor. */
+ if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
+ decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
+ else
+ {
+ /* Allow for dummy arguments and other good things. */
+ if (POINTER_TYPE_P (TREE_TYPE (decl)))
+ decl = build_fold_indirect_ref_loc (input_location, decl);
+
+ /* Check if '_data' is an array descriptor. If it is not,
+ the array must be one of the components of the class
+ object, so return a normal array reference. */
+ if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
+ gfc_class_data_get (decl))))
+ return build4_loc (input_location, ARRAY_REF, type, base,
+ offset, NULL_TREE, NULL_TREE);
+ }
+
+ span = gfc_class_vtab_size_get (decl);
+ }
+ else if (GFC_DECL_SUBREF_ARRAY_P (decl))
+ span = GFC_DECL_SPAN (decl);
+ else
+ gcc_unreachable ();
}
- else if (GFC_DECL_SUBREF_ARRAY_P (decl))
- span = GFC_DECL_SPAN(decl);
+ else if (vptr)
+ span = gfc_vptr_size_get (vptr);
else
gcc_unreachable ();