summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorvehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-29 16:54:24 +0000
committervehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-29 16:54:24 +0000
commit3ef41a6eba3f9b1212d3fe8beaf5cc4a7cea7d59 (patch)
treee4e0a9b1cd9f9d0b25895fe00681f2f8dc699f04 /gcc/fortran
parent80a02663120ced955fc574f2d4f74b727e4f0986 (diff)
downloadgcc-3ef41a6eba3f9b1212d3fe8beaf5cc4a7cea7d59.tar.gz
gcc/fortran/ChangeLog:
2016-03-29 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/70397 * trans-expr.c (gfc_class_len_or_zero_get): Add function to return a constant zero tree, when the class to get the _len component from is not unlimited polymorphic. (gfc_copy_class_to_class): Use the new function. * trans.h: Added interface of new function gfc_class_len_or_zero_get. gcc/testsuite/ChangeLog: 2016-03-29 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/70397 * gfortran.dg/unlimited_polymorphic_25.f90: New test. * gfortran.dg/unlimited_polymorphic_26.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234528 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/trans-expr.c26
-rw-r--r--gcc/fortran/trans.h1
3 files changed, 35 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index cf95d6ffc95..5ab7d3ff285 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2016-03-29 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/70397
+ * trans-expr.c (gfc_class_len_or_zero_get): Add function to return a
+ constant zero tree, when the class to get the _len component from is
+ not unlimited polymorphic.
+ (gfc_copy_class_to_class): Use the new function.
+ * trans.h: Added interface of new function gfc_class_len_or_zero_get.
+
2016-03-28 Alessandro Fanfarillo <fanfarillo.gcc@gmail.com>
* trans-decl.c (gfc_build_builtin_function_decls):
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 4baadc84ef0..8d039a670b5 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -173,6 +173,29 @@ gfc_class_len_get (tree decl)
}
+/* Try to get the _len component of a class. When the class is not unlimited
+ poly, i.e. no _len field exists, then return a zero node. */
+
+tree
+gfc_class_len_or_zero_get (tree decl)
+{
+ tree len;
+ /* For class arrays decl may be a temporary descriptor handle, the vptr is
+ then available through the saved descriptor. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl)
+ && GFC_DECL_SAVED_DESCRIPTOR (decl))
+ decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
+ if (POINTER_TYPE_P (TREE_TYPE (decl)))
+ decl = build_fold_indirect_ref_loc (input_location, decl);
+ len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
+ CLASS_LEN_FIELD);
+ return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (len), decl, len,
+ NULL_TREE)
+ : integer_zero_node;
+}
+
+
/* Get the specified FIELD from the VPTR. */
static tree
@@ -250,6 +273,7 @@ gfc_vptr_size_get (tree vptr)
#undef CLASS_DATA_FIELD
#undef CLASS_VPTR_FIELD
+#undef CLASS_LEN_FIELD
#undef VTABLE_HASH_FIELD
#undef VTABLE_SIZE_FIELD
#undef VTABLE_EXTENDS_FIELD
@@ -1120,7 +1144,7 @@ gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
if (unlimited)
{
if (from != NULL_TREE && unlimited)
- from_len = gfc_class_len_get (from);
+ from_len = gfc_class_len_or_zero_get (from);
else
from_len = integer_zero_node;
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index add0ceaa3db..512615ab1e4 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -365,6 +365,7 @@ tree gfc_class_set_static_fields (tree, tree, tree);
tree gfc_class_data_get (tree);
tree gfc_class_vptr_get (tree);
tree gfc_class_len_get (tree);
+tree gfc_class_len_or_zero_get (tree);
gfc_expr * gfc_find_and_cut_at_last_class_ref (gfc_expr *);
/* Get an accessor to the class' vtab's * field, when a class handle is
available. */