Hi all,
I'm working on a patch to fix the "multiple decls per function"
issue. Current status is good, except for handling of array
arguments, and I need a hand in understand how this is handled. This
is not strictly related to my patch, but lies in the code generated
by the front-end in its current state, although it is uncovered by
the patch :( I'd be happy to get other maintainers' insight on this
issue, because I'm not too used to array-handling at the tree level.
My patch enables us to reuse already created function decls for a
given function instead of creating a new one each time. If the
function declaration comes first or if an explicit interface is
used,
we can create the function decl easily from the formal arglist. For
implicit interfaces, I chose to recreate the list of argument types
simply by looking at the types in the actual arglist (in its tree
form).
However, in the case where an array is used as argument, that
doesn't
give the same results. For an explicit interface of type
subroutine test(x)
integer x(1)
end subroutine test
the front-end generates for the type of the argument the
following tree:
<pointer_type 0x2aae4c1bc3c0
type <array_type 0x2aae4c1bc000 type <real_type
0x2aae4c1383c0 real(kind=4)>
type_2 SF
size <integer_cst 0x2aae4c11ea50 constant invariant 32>
unit size <integer_cst 0x2aae4c11e6c0 constant
invariant 4>
align 32 symtab 0 alias set -1 canonical type
0x2aae4c1bc000 domain <integer_type 0x2aae4c1bc300>
pointer_to_this <pointer_type 0x2aae4c1bc3c0>>
unsigned type_2 DI
size <integer_cst 0x2aae4c11eb40 constant invariant 64>
unit size <integer_cst 0x2aae4c11eb70 constant invariant 8>
align 64 symtab 0 alias set -1 canonical type
0x2aae4c1bc3c0>
which is, as far as I understand, correctly marked as an array (see
the "type_2", which is TYPE_LANG_FLAG_2, aka GFC_ARRAY_TYPE_P. On
the
other hand, when the front-end generates code for the following call
(with implicit interface):
integer x(1)
call test(x)
it gives the following type to the x argument :
<pointer_type 0x2b41eda80780
type <array_type 0x2b41eda800c0 type <real_type
0x2b41ed9fc3c0 real(kind=4)>
type_2 SF
size <integer_cst 0x2b41ed9e2a50 constant invariant 32>
unit size <integer_cst 0x2b41ed9e26c0 constant
invariant 4>
align 32 symtab 0 alias set -1 canonical type
0x2b41eda800c0 domain <integer_type 0x2b41eda803c0>
pointer_to_this <pointer_type 0x2b41eda80780>>
unsigned DI
size <integer_cst 0x2b41ed9e2b40 constant invariant 64>
unit size <integer_cst 0x2b41ed9e2b70 constant invariant 8>
align 64 symtab 0 alias set -1 canonical type
0x2b41eda80780>
It looks right, but it doesn't have the "type_2" flag, ie no
GFC_ARRAY_TYPE_P. Later on, this issue will trigger various asserts
in the front-end (starting with gfc_build_dummy_array_decl, at
fortran/trans-decl.c:740). I believe these asserts are right, and
the
arguments should be marked with GFC_ARRAY_TYPE_P. Do others agree
with this conclusion, and does anyone know where I can start looking
for a place to add it?
Thanks,
FX
PS: my current patch is attached, it regtests and works for valid
code that doesn't involve arrays :)
The testcase that reveals the issue I describe here is:
program test
real dist(1)
dist = 1.0
call f(dist)
end program test
subroutine f(dist)
real dist(1)
if (dist(1) > 0) call abort
end
If you put the subroutine before the main program, the function decl
is generated from the formal arglist, and it works fine. If you keep
it in the order given here, the function decl's args types (ie
TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
PS2: this patch allows good inlining of non-contained procedures, as
well as the -fwhole-program option. It should also allow better
optimization in the middle-end (by having a valid call-graph).