http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31016

--- Comment #7 from Tobias Burnus <burnus at gcc dot gnu.org> ---
(In reply to Thomas Koenig from comment #6)
> Working on it a little bit.

I believe that the middle end prefers the use of ARRAY_RANGE_REF to the use of
memcpy. The reason is that with ARRAY_RANGE_REF it knows what type it has while
memcpy transfers everything into a pointer - and it cannot then simply recover
the value.

For a range-ref example, see class_array_data_assign - or Ada.


For instance, 
    b = a(1:12)
can be represented as

  lhs = gfc_get_descriptor_dimension (lhs_desc);
  rhs = gfc_get_descriptor_dimension (rhs_desc);

  lhs = build4_loc (input_location, ARRAY_RANGE_REF, type, lhs,
                    lhs_offset, NULL_TREE, NULL_TREE);
  rhs = build4_loc (input_location, ARRAY_RANGE_REF, type, rhs,
                    rhs_offset, NULL_TREE, NULL_TREE);
followed by
  gfc_add_modify (block, lhs, rhs);

Note that the number of elements is contained in the "type". In the example
above, one can use:
  type = TREE_TYPE (lhs)   (add before before the build4_loc call)
as "lhs" is a full array with a known size.

If one doesn't have a full array (or an allocatable array), one has to build
the type oneself - for instance by using:

  type = 
    build_array_type (type, build_range_type (gfc_array_index_type,
                                              gfc_index_zero_node,
                                              number_of_elements));

where type is either gfc_typenode_for_spec (&expr2->ts) or, e.g.,
  gfc_get_element_type (TREE_TYPE (lhs)).


Disclaimer: The example above should be correct. However, I have not fully
understood how RANGE_REF works, i.e. what the last two arguments (here:
NULL_TREE) do.

Reply via email to