Hi All,
Although I had undertaken to concentrate on PDTs, PR99819 so intrigued me
that I became locked into it :-( After extensive, fruitless rummaging
through decl.c and trans-decl.c, I realised that the problem was far
simpler than it seemed and that it lay in class.c. After that PR was fixed,
PR46691 was a trivial follow up.
The comments in the patch explain the fixes. I left a TODO for the extent
checking of assumed size class arrays. I will try to fix it before pushing.
Regtested on FC33/x86_64 and checked against the 'other brand'. OK for
12-branch and, perhaps, 11-branch?
Regards
Paul
Fortran: Assumed and explicit size class arrays [PR46691/99819].
2021-05-06 Paul Thomas
gcc/fortran/ChangeLog
PR fortran/46691
PR fortran/99819
* class.c (gfc_build_class_symbol): Class array types that are
not deferred shape or assumed rank are given a unique name and
placed in the procedure namespace.
* trans-array.c (gfc_trans_g77_array): Obtain the data pointer
for class arrays.
(gfc_trans_dummy_array_bias): Suppress the runtime error for
extent violations in explicit shape class arrays because it
always fails.
* trans-expr.c (gfc_conv_procedure_call): Handle assumed size
class actual arguments passed to non-descriptor formal args by
using the data pointer, stored as the symbol's backend decl.
gcc/testsuite/ChangeLog
PR fortran/46691
PR fortran/99819
* gfortran.dg/class_dummy_6.f90: New test.
* gfortran.dg/class_dummy_6.f90: New test.
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 89353218417..93118ad3455 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -630,6 +630,7 @@ gfc_get_len_component (gfc_expr *e, int k)
component '_vptr' which determines the dynamic type. When this CLASS
entity is unlimited polymorphic, then also add a component '_len' to
store the length of string when that is stored in it. */
+static int ctr = 0;
bool
gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
@@ -645,13 +646,6 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
gcc_assert (as);
- if (*as && (*as)->type == AS_ASSUMED_SIZE)
-{
- gfc_error ("Assumed size polymorphic objects or components, such "
- "as that at %C, have not yet been implemented");
- return false;
-}
-
if (attr->class_ok)
/* Class container has already been built. */
return true;
@@ -693,7 +687,30 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
else
ns = ts->u.derived->ns;
- gfc_find_symbol (name, ns, 0, &fclass);
+ /* Although this might seem to be counterintuitive, we can build separate
+ class types with different array specs because the TKR interface checks
+ work on the declared type. All array type other than deferred shape or
+ assumed rank are added to the function namespace to ensure that they
+ are properly distinguished. */
+ if (attr->dummy && !attr->codimension && (*as)
+ && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK))
+{
+ char *sname;
+ ns = gfc_current_ns;
+ gfc_find_symbol (name, ns, 0, &fclass);
+ /* If a local class type with this name already exists, update the
+ name with an index. */
+ if (fclass)
+ {
+ fclass = NULL;
+ sname = xasprintf ("%s_%d", name, ++ctr);
+ free (name);
+ name = sname;
+ }
+}
+ else
+gfc_find_symbol (name, ns, 0, &fclass);
+
if (fclass == NULL)
{
gfc_symtree *st;
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index e99980fd223..6d38ea78273 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6524,7 +6524,14 @@ gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
/* Set the pointer itself if we aren't using the parameter directly. */
if (TREE_CODE (parm) != PARM_DECL)
{
- tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
+ tmp = GFC_DECL_SAVED_DESCRIPTOR (parm);
+ if (sym->ts.type == BT_CLASS)
+ {
+ tmp = build_fold_indirect_ref_loc (input_location, tmp);
+ tmp = gfc_class_data_get (tmp);
+ tmp = gfc_conv_descriptor_data_get (tmp);
+ }
+ tmp = convert (TREE_TYPE (parm), tmp);
gfc_add_modify (&init, parm, tmp);
}
stmt = gfc_finish_block (&init);
@@ -6626,7 +6633,8 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
&& VAR_P (sym->ts.u.cl->backend_decl))
gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
- checkparm = (as->type == AS_EXPLICIT
+ /* TODO: Fix the exclusion of class arrays from extent checking. */
+ checkparm = (as->type == AS_EXPLICIT && !is_classarray
&& (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 213f32b0a67..5f5479561c2 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6420,6 +6420,15 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol *