Steve Kargl | 4 Jul 20:10
Picon

Status of deferred type parameters and ALLOCATE

All, 

Here's a short status report on the deferred type parameter
and F2003 ALLOCATE features that I've been implementing.  
I'm making slow but steady progress on both features.
Unfortunately, the two features are sufficiently intertwined
that one cannot be committed without the other (imho).  
Here's a preview, consider

   program test
   implicit none
   character(:), allocatable :: fmt
   allocate(character(3) :: fmt)
   fmt = 'abc'
   print *, fmt, len(fmt)
   deallocate(fmt)
   allocate(character(6) :: fmt)
   fmt = 'abcdef'
   print *, fmt, len(fmt)
   end program test 

REMOVE:kargl[293] gfc4x -o z -fdump-tree-original t.f90
REMOVE:kargl[294] ./z
 abc              6
 abcdef           6

Note 1: The 6 in the first line of output should probably
        be 3.  This difference is caused by the way I currently
        fiddle with the length component of the charlen structure
        during the parsing and matching stage.
        In particular, 

        allocate(character(3) :: fmt) ! Set ts.cl->length = 3
        deallocate(fmt)               ! Set ts.cl->length = NULL
        allocate(character(6) :: fmt) ! Set ts.cl->length = 6

        So, by the time gfortran gets to the translation to trees
        stage, the translation stage never sees the value 3.  It's
        as if one wrote 'character(len=6) :: fmt' instead of the
        declaration with the deferred type parameter.

Note 2: No changes to the trans-* files were required to get the
        above outputi, which is unexpected (see below).

Note 3: I've only considered the use of deferred type parameters
        with ALLOCATE.  The above program can be written as

        program test
        implicit none
        character(:), allocatable :: fmt
        fmt = 'abc'
        print *, fmt, len(fmt)
        fmt = 'abcdef'
        print *, fmt, len(fmt)
        end program test 

        where on assignment one gets implicit allocation and
        deallocation if needed.

Finally, if one looks at the -fdump-tree-original, one sees
(with some stuff removed)

  character(kind=1)[1:6] * fmt;

  {
    void * D.1502;

    D.1502 = __builtin_malloc (6);
    fmt = (character(kind=1)[1:6] *) D.1502;
  }
  __builtin_memmove ((void *) fmt, (void *) &"abc"[1]{lb: 1 sz: 1}, 3);
  __builtin_memset ((void *) fmt + 3, 32, 3);

which isn't what I think we want.  I think this should look something
like

  character(kind=1) *fmt;
  integer(kind=4) deferred_len;

  deferred_len = 3;
  fmt = __builtin_malloc (deferred_len);
  __builtin_memmove ((void *)fmt, (void *) &"abc"[1]{lb:1 sz:1}, deferred_len);

with, of course, the appropriate checking for 'Out of Memory' and
valid deferred_len values.  To achieve the above, I think we may 
need to add a new member to gfc_charlen to hold the deferred_len,
and leave cl->length = NULL.  This should cause all sorts of 
havoc in the trans-* layer.

--

-- 
Steve


Gmane