Comments

Dear All,
I have been much longer in preparing the class array patch than
intended simply because I wanted to reach the point where it would do
something useful :-) Well here it is. Whilst I realise that we are in
phase 3, this patch is pretty bomb-proof simply because class arrays
did not work at all, previously. Also, we are a few months from
release yet and I am sure that any significant regressions will appear
by then.
I have to confess that it is still not as consistent and well ordered
as I would like. I started the process of cleaning up, as will be
apparent in the first, new block in trans-expr.c; when this reaches
critical mass, it will be broken out into trans-class.c.
I should record here that Tobias has been extraordinarily helpful in
providing feedback, testcases and the coarray part.
Between now and the release of 4.7, I will continue to bug fix and
clean up the implementation of class arrays. However, I am pleased to
say that it already does better than most of the other brands that we
have had access to, with the exception of NAG. The testcase
class_array_3.f03 is a quick sort program that could be generalised to
work with any comparison operator. Only NAG was able to deal with
this.
All this said, I should record where gfortran is still broken, is a
bit untidy or does not yet produce correct code:
(i) Class subarray references usually produce ICEs. eg
type t
integer :: i
end type t
class(t),allocatable :: A(:)
allocate (A(2))
A(1:2)%i = [33,66] ! <<<< HERE
end
See comment #2 of PR46356
(ii) Vector indices do not work. See class_array_3.f03 for a place
where a do loop must be used instead of:
a = tmp(index_array), where a and tmp are class arrays. This produces
a segfault because the class array temporary that is produced is not
allocated and, still worse is nullified. In addition, the temporary is
not necessary, since no pointers are involved and the variables are
different. For some reason, moving the index array to the lhs, causes
the massage, "Variable must not be polymorphic in assignment at (1)"
so that the statement cannot be recognised as a defined assignment.
(iii) gfc_trans_class_array_init_assign and gfc_trans_allocate make
use of front-endery to produce a call to gfc_trans_call, in order to
benefit from the scalarizer in element by element copies. These bits
of code can be combined with advantage and moved to (trans-)class.c.
(iv) gfc_add_loop_ss_code does not produce a temporary for class
scalars, since their size can vary according to the dynamic type.
Whilst this has not been seen to fail, it should be determined if this
works generally.
(v) build_class_array_ref is an example of a place where manipulation
of front-end expressions is used heavily to generate the class
declaration. This could be done in gfc_conv_expr by adding an gfc_se
field for the class decl and storing it on the fly.
(vi) Numerous places exist, where the new class API should be used; eg
in structure_alloc_comps.
(vii) GFC_DECL_CLASS is only set for variable declarations; field and
parm dels should be set too.
(viii) Whilst some intrinsics now work, such as LBOUND, UBOUND, SIZE,
MOVE_ALLOC, ALLOCATED and ASSOCIATED, there are still others that need
to be implemented.
(ix) match.c:5247 is a horrible expression to distinguish class
arrays. gfc_is_class_array_ref does not work there and causes numerous
regressions. This must be understood and corrected.
(x) PRs are welcome! At least it is a sign that people are trying to
use this feature and I will do my best to fix them.
Boostrapped and regtested on x86_64/FC9 - OK for trunk?
Cheers
Paul
2011-12-11 Paul Thomas <pault@gcc.gnu.org>
Tobias Burnus <burnus@gcc.gnu.org>
PR fortran/41539
PR fortran/43214
PR fortran/43969
PR fortran/44568
PR fortran/46356
PR fortran/46990
PR fortran/49074
* interface.c(symbol_rank): Return the rank of the _data
component of class objects.
(compare_parameter): Also compare the derived type of the class
_data component for type mismatch. Similarly, return 1 if the
formal and _data ranks match.
(compare_actual_formal): Do not compare storage sizes for class
expressions. It is an error if an actual class array, passed to
a formal class array is not full.
* trans-expr.c (gfc_class_data_get, gfc_class_vptr_get,
gfc_vtable_field_get, gfc_vtable_hash_get, gfc_vtable_size_get,
gfc_vtable_extends_get, gfc_vtable_def_init_get,
gfc_vtable_copy_get): New functions for class API.
(gfc_conv_derived_to_class): For an array reference in an
elemental procedure call retain the ss to provide the
scalarized array reference. Moved in file.
(gfc_conv_class_to_class): New function.
(gfc_conv_subref_array_arg): Use the type of the
class _data component as a basetype.
(gfc_conv_procedure_call): Ensure that class array expressions
have both the _data reference and an array reference. Use
gfc_conv_class_to_class to handle class arrays for elemental
functions in scalarized loops, class array elements and full
class arrays. Use a call to gfc_conv_subref_array_arg in order
that the copy-in/copy-out for passing class arrays to derived
type arrays occurs correctly.
(gfc_conv_expr): If it is missing, add the _data component
between a class object or component and an array reference.
(gfc_trans_class_array_init_assign): New function.
(gfc_trans_class_init_assign): Call it for array expressions.
* trans-array.c (gfc_add_loop_ss_code): Do not use a temp for
class scalars since their size will depend on the dynamic type.
(build_class_array_ref): New function.
(gfc_conv_scalarized_array_ref): Call build_class_array_ref.
(gfc_array_init_size): Add extra argument, expr3, that represents
the SOURCE argument. If present,use this for the element size.
(gfc_array_allocate): Also add argument expr3 and use it when
calling gfc_array_init_size.
(structure_alloc_comps): Enable class arrays.
* class.c (gfc_add_component_ref): Carry over the derived type
of the _data component.
(gfc_add_class_array_ref): New function.
(class_array_ref_detected): New static function.
(gfc_is_class_array_ref): New function that calls previous.
(gfc_is_class_scalar_expr): New function.
(gfc_build_class_symbol): Throw not implemented error for
assumed size class arrays. Remove error that prevents
CLASS arrays.
(gfc_build_class_symbol): Prevent pointer/allocatable conflict.
Also unset codimension.
(gfc_find_derived_vtab): Make 'copy' elemental and set the
intent of the arguments accordingly.:
* trans-array.h : Update prototype for gfc_array_allocate.
* array.c (gfc_array_dimen_size): Return failure if class expr.
(gfc_array_size): Likewise.
* gfortran.h : New prototypes for gfc_add_class_array_ref,
gfc_is_class_array_ref and gfc_is_class_scalar_expr.
* trans-stmt.c (trans_associate_var): Exclude class targets
from test. Move the allocation of the _vptr to an earlier time
for class objects.
(trans_associate_var): Assign the descriptor directly for class
arrays.
(gfc_trans_allocate): Add expr3 to gfc_array_allocate arguments.
Convert array element references into sections. Do not invoke
gfc_conv_procedure_call, use gfc_trans_call instead.
* expr.c (gfc_get_corank): Fix for BT_CLASS.
(gfc_is_simply_contiguous): Exclude class from test.
* trans.c (gfc_build_array_ref): Include class array refs.
* trans.h : Include prototypes for class API functions that are
new in trans-expr. Define GFC_DECL_CLASS(node).
* resolve.c (check_typebound_baseobject ): Remove error for
non-scalar base object.
(resolve_allocate_expr): Ensure that class _data component is
present. If array, call gfc_expr_to_intialize.
(resolve_select): Remove scalar error for SELECT statement as a
temporary measure.
(resolve_assoc_var): Update 'target' (aka 'selector') as
needed. Ensure that the target expression has the right rank.
(resolve_select_type): Ensure that target expressions have a
valid locus.
(resolve_allocate_expr, resolve_fl_derived0): Fix for BT_CLASS.
* trans-decl.c (gfc_get_symbol_decl): Set GFC_DECL_CLASS, where
appropriate.
(gfc_trans_deferred_vars): Get class arrays right.
* match.c(select_type_set_tmp): Add array spec to temporary.
(gfc_match_select_type): Allow class arrays.
* check.c (array_check): Ensure that class arrays have refs.
(dim_corank_check, dim_rank_check): Retrun success if class.
* primary.c (gfc_match_varspec): Fix for class arrays and
co-arrays. Make sure that class _data is present.
(gfc_match_rvalue): Handle class arrays.
*trans-intrinsic.c (gfc_conv_intrinsic_size): Add class array
reference.
(gfc_conv_allocated): Add _data component to class expressions.
(gfc_add_intrinsic_ss_code): ditto.
* simplify.c (simplify_cobound): Fix for BT_CLASS.
(simplify_bound): Return NULL for class arrays.
(simplify_cobound): Obtain correct array_spec. Use cotype as
appropriate. Use arrayspec for bounds.
2011-12-11 Paul Thomas <pault@gcc.gnu.org>
Tobias Burnus <burnus@gcc.gnu.org>
PR fortran/41539
PR fortran/43214
PR fortran/43969
PR fortran/44568
PR fortran/46356
PR fortran/46990
PR fortran/49074
* gfortran.dg/class_array_1.f03: New.
* gfortran.dg/class_array_2.f03: New.
* gfortran.dg/class_array_3.f03: New.
* gfortran.dg/class_array_4.f03: New.
* gfortran.dg/class_array_5.f03: New.
* gfortran.dg/class_array_6.f03: New.
* gfortran.dg/class_array_7.f03: New.
* gfortran.dg/class_array_8.f03: New.
* gfortran.dg/coarray_poly_1.f90: New.
* gfortran.dg/coarray_poly_2.f90: New.
* gfortran.dg/coarray/poly_run_1.f90: New.
* gfortran.dg/coarray/poly_run_2.f90: New.
* gfortran.dg/class_to_type_1.f03: New.
* gfortran.dg/type_to_class_1.f03: New.
* gfortran.dg/typebound_assignment_3.f03: Remove the error.
* gfortran.dg/auto_dealloc_2.f90: Occurences of __builtin_free
now 2. * gfortran.dg/auto_dealloc_2.f90: Occurences of __builtin_free
* gfortran.dg/class_19.f03: Occurences of __builtin_free now 8.

Dear Paul, dear all,
first, thanks again for the patch.
Paul Richard Thomas wrote:
> Boostrapped and regtested on x86_64/FC9 - OK for trunk?
I have now re-read the patch and it is OK from my side. It wouldn't harm
is someone else with experience with CLASS or with the scalarizer could
also read the patch (before or after committal).
Nits:
> * gfortran.dg/auto_dealloc_2.f90: Occurences of __builtin_free> now 2. * gfortran.dg/auto_dealloc_2.f90: Occurences of __builtin_free> * gfortran.dg/class_19.f03: Occurences of __builtin_free now 8.
Missing line break after "2.".
> + for (ref = expr->ref; ref; ref = ref->next)> + {> + if (ref->type == REF_COMPONENT> + && ref->u.c.component->ts.type == BT_CLASS> + && ref->next&& ref->next->type == REF_COMPONENT> + && strcmp (ref->next->u.c.component->name, "_data") == 0> + && ref->next->next> + && ref->next->next->type == REF_ARRAY> + && ref->next->next->u.ar.type != AR_ELEMENT)> + {> + ts =&ref->u.c.component->ts;> + class_ref = ref;> + break;> + } > + }
Those lines look wrongly indented.
> /* Generate code to initialize an allocate an array. Statements are added to
Untouched by your patch, but could you nevertheless fix the sentence by
changing "an" to "and"?
> + #if 0> + if (expr->ts.type == BT_CLASS&& expr3)> + {> + tmp = build_int_cst (unsigned_char_type_node, 0);>> + /* With class objects, it is best to play safe and null the> + memory because we cannot know if dynamic types have allocatable> + components or not..> + OOP-TODO: Determine if this is necessary or not. */
and
> + else if (al->expr->ts.type == BT_CLASS&& code->expr3)> + {> + /* With class objects, it is best to play safe and null the> + memory because we cannot know if dynamic types have allocatable> + components or not. */> + tmp = build_call_expr_loc (input_location,> + builtin_decl_explicit (BUILT_IN_MEMSET),> + 3, se.expr, integer_zero_node, memsz);> + gfc_add_expr_to_block (&se.pre, tmp);> + }
Can the #if 0 ... #endif block be removed? Seemingly, you have not found
a case where it is not initialized. Additionally, I think the same
applies to the the second quote: If there is an expr3 (i.e. MOLD= or
SOURCE=) with a nonpolymorphic or with a polymorphic source-expr, either
the default initialization or the assignment should take care of the
allocatable components and similar issues.
If you really prefer to keep it (or them), can you fill a
missed-optimization PR?
After committal, can you write a quip for
http://gcc.gnu.org/wiki/GFortran#GCC4.7 ?
(Additionally, http://gcc.gnu.org/wiki/OOP and maybe
http://gcc.gnu.org/wiki/Fortran2003 could be updated.)
Tobias

Dear Tobias,
On Sun, Dec 11, 2011 at 7:39 PM, Tobias Burnus <burnus@net-b.de> wrote:
> Dear Paul, dear all,>> first, thanks again for the patch.
Thank you for the continuous reviewing over the last couple of months
- also to Dominique, Salvatore and Damian; all of whom have kept the
test cases coming in.
>>> Paul Richard Thomas wrote:>>>> Boostrapped and regtested on x86_64/FC9 - OK for trunk?
Committed as revision 182210 with comments and corrections taken on board.
Cheers
Paul