Hello,
Le 11/02/2024 à 03:00, Steve Kargl a écrit :
All, consider this simple code:
module foo
contains
subroutine bar
character(len=:), allocatable :: s(:)
call bah(s)
end subroutine bar
end module foo
If one compiles with -fdump-tree-original, one see (with some pruning)
void bar ()
{
integer(kind=8) .s;
struct array01_character(kind=1) s;
The above two lines seem to be ok.
bitsizetype D.4319;
sizetype D.4320;
try
{
D.4319 = (bitsizetype) (sizetype) NON_LVALUE_EXPR <.s> * 8;
D.4320 = (sizetype) NON_LVALUE_EXPR <.s>;
s.data = 0B;
s.dtype = {.elem_len=(unsigned long) .s, .version=0, .rank=1, .type=6};
bah ((character(kind=1)[0:][1:.s] * restrict) s.data, .s);
}
This is bad. .s is undefined. I've trace this to trans-array.cc:11531
if (sym->ts.type == BT_CHARACTER
&& !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
{
gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
gfc_trans_vla_type_sizes (sym, &init);
The problem here is that sym->ts.u.cl->length == NULL. If I change
the conditional to
if (sym->ts.type == BT_CHARACTER
&& sym->ts.u.cl->length
&& !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
No, I think sym->ts.u.cl->length == NULL is correct for deferred length.
It is set only when there is an expression defining the length:
character(len=size(somevar)) :: s(:)
then the option -fdump-tree-original produces
void bar ()
{
integer(kind=8) .s;
struct array01_character(kind=1) s;
try
{
s.data = 0B;
s.dtype = {.elem_len=(unsigned long) .s, .version=0, .rank=1, .type=6};
bah ((character(kind=1)[0:][1:.s] * restrict) s.data, .s);
}
which looks good except I don't know what the reference to .s here
means. Is this correct or should we set .s to zero by artificially
setting sym->ts.u.cl->length to, say, zero length?
Setting the variable .s to zero should be correct in any case, but it's
not the same as setting the expression.
I think you can use
if (sym->ts.deferred)
gfc_add_modify (
&init,
sym->ts.u.cl->backend_decl,
build_zero_cst (TREE_TYPE (sym->ts.u.cl->backen_decl))
);
to set .s to zero.
Actually, setting to any value should be correct (including -1), as the
value should not be used as long as the data pointer is NULL.
What is not clear is whether the values of D.4319 and D.4320 need
update when memory is allocated for s. I think those variables are
referenced in the type of s (but it's not visible in the dump), and may
need update when the value of .s changes.
I hope it helps.
Mikael