From: Mikael Morin <[email protected]>
Fortran-tested on aarch64-unknown-linux-gnu.
It's simple enough; I plan to push it to mainline, today or tomorrow.
-- >8 --
The testcase shows one example where we use a class container type as
element type of an array descriptor. This causes the element length to be
initialized to the wrong value, with an effect visible by the ASSOCIATED
intrinsic at execution time.
This change fixes the problem by detecting the class container and
unwrapping it before using it for array descriptor type creation.
PR fortran/128103
gcc/fortran/ChangeLog:
* trans-array.cc (gfc_conv_expr_descriptor): Unwrap any class
container from the type to use as array descriptor element type.
gcc/testsuite/ChangeLog:
* gfortran.dg/associated_9.f90: New test.
---
gcc/fortran/trans-array.cc | 8 +++++-
gcc/testsuite/gfortran.dg/associated_9.f90 | 32 ++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/associated_9.f90
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2045424a861..1a0415b4462 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8587,7 +8587,13 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
subobject for a subreference of the array. */
if (expr->ts.type == BT_CHARACTER
|| (subref_array_target && !se->direct_byref))
- parmtype = gfc_typenode_for_spec (&expr->ts);
+ {
+ gfc_typespec *ts = &expr->ts;
+ if (ts->type == BT_CLASS
+ && ts->u.derived->attr.is_class)
+ ts = &ts->u.derived->components->ts;
+ parmtype = gfc_typenode_for_spec (ts);
+ }
else
parmtype = gfc_get_element_type (TREE_TYPE (desc));
diff --git a/gcc/testsuite/gfortran.dg/associated_9.f90
b/gcc/testsuite/gfortran.dg/associated_9.f90
new file mode 100644
index 00000000000..06dea871a36
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associated_9.f90
@@ -0,0 +1,32 @@
+! { dg-do run }
+! { dg-additional-options {-fdump-tree-original} }
+!
+! PR fortran/128103
+! Check the type and element length of the array descriptor for the polymorphic
+! pointer X(:) used as TARGET of the ASSOCIATED intrinsic. We used to generate
+! a descriptor with class container element type.
+!
+! There are two array descriptor variables of type T1 used as actual argument,
+! one for the call to SUB, and one for the TARGET of the call to ASSOCIATED:
+! { dg-final { scan-tree-dump-times {struct array01_t1 parm\.\d+;} 2
{original} } }
+! Each of them initialized with an element length of 4:
+! { dg-final { scan-tree-dump-times {parm\.\d+\.dtype = .\.elem_len=4} 2
{original} } }
+
+program prog
+ implicit none
+ integer, parameter :: n = 5
+ type :: t1
+ integer :: c1
+ end type
+ type(t1), target :: a(n)
+ integer :: i
+ a = [ (t1(i*i+2), i=1,n) ]
+ call sub(a)
+contains
+ subroutine sub(x)
+ class(t1), pointer, intent(in) :: x(:)
+ type(t1), pointer :: p(:)
+ p => a
+ if (.not. associated(p, x(:))) error stop 1
+ end subroutine
+end program
--
2.53.0