Commit 728557fd by Andre Vehreschild

re PR fortran/70397 (ice while allocating ultimate polymorphic)

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.

From-SVN: r234528
parent da178d56
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):
......
......@@ -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;
}
......
......@@ -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. */
......
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.
2016-03-29 Thomas Schwinge <thomas@codesourcery.com>
PR testsuite/64177
......
! { dg-do run }
!
! Test contributed by Valery Weber <valeryweber@hotmail.com>
module mod
TYPE, PUBLIC :: base_type
END TYPE base_type
TYPE, PUBLIC :: dict_entry_type
CLASS( * ), ALLOCATABLE :: key
CLASS( * ), ALLOCATABLE :: val
END TYPE dict_entry_type
contains
SUBROUTINE dict_put ( this, key, val )
CLASS(dict_entry_type), INTENT(INOUT) :: this
CLASS(base_type), INTENT(IN) :: key, val
INTEGER :: istat
ALLOCATE( this%key, SOURCE=key, STAT=istat )
end SUBROUTINE dict_put
end module mod
program test
use mod
type(dict_entry_type) :: t
type(base_type) :: a, b
call dict_put(t, a, b)
if (.NOT. allocated(t%key)) call abort()
select type (x => t%key)
type is (base_type)
class default
call abort()
end select
deallocate(t%key)
end
! { dg-do run }
!
! Test contributed by Valery Weber <valeryweber@hotmail.com>
module mod
TYPE, PUBLIC :: dict_entry_type
CLASS( * ), ALLOCATABLE :: key
CLASS( * ), ALLOCATABLE :: val
END TYPE dict_entry_type
contains
SUBROUTINE dict_put ( this, key, val )
CLASS(dict_entry_type), INTENT(INOUT) :: this
CLASS(*), INTENT(IN) :: key, val
INTEGER :: istat
ALLOCATE( this%key, SOURCE=key, STAT=istat )
ALLOCATE( this%val, SOURCE=val, STAT=istat )
end SUBROUTINE dict_put
end module mod
program test
use mod
type(dict_entry_type) :: t
call dict_put(t, "foo", 42)
if (.NOT. allocated(t%key)) call abort()
select type (x => t%key)
type is (CHARACTER(*))
if (x /= "foo") call abort()
class default
call abort()
end select
deallocate(t%key)
if (.NOT. allocated(t%val)) call abort()
select type (x => t%val)
type is (INTEGER)
if (x /= 42) call abort()
class default
call abort()
end select
deallocate(t%val)
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment