4 Jul 20:10
Status of deferred type parameters and ALLOCATE
Steve Kargl <sgk <at> troutmask.apl.washington.edu>
2009-07-04 18:10:47 GMT
2009-07-04 18:10:47 GMT
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
RSS Feed