This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, Fortran, OOP] PR 45290/45271: pointer initialization / vtab init
On 08/20/2010 02:11 PM, Janus Weil wrote:
well, I have been wondering about this myself. I think what currently
happens for a module function which is used as an initialization
target in the header of the module is the following:
1) When translating the initializer, we create a backend_decl via
gfc_get_extern_function_decl.
2) When generating the function code, we create another one using
gfc_create_function_decl (overriding the old one).
While the middle end seems to handle this alright
I think the middle end does not handle it correctly - you are just lucky
that it does not see any optimization possibility for your code. And if
it does not do some "clever" optimizations it works as the function name
is the same - which is all what counts on assembler level.
@@ -1608,9 +1622,11 @@ build_function_decl (gfc_symbol * sym, bool global
tree result_decl;
gfc_formal_arglist *f;
- gcc_assert (!sym->backend_decl);
gcc_assert (!sym->attr.external);
+ if (sym->backend_decl)
+ return;
I think that's better - but I wonder whether the generated DECL ends up
in the wrong scope. Procedure declarations generated through
gfc_get_extern_function_decl are in the global scope:
/* By construction, the external function cannot be
a contained procedure. */ [...]
current_function_decl = NULL_TREE;
push_cfun (cfun);
gfc_create_function_decl (gsym->ns, true);
where global=true, which hoists the decl into the global namespace:
if (global)
pushdecl_top_level (fndecl);
If I now look at gfc_generate_module_code, I see:
ns->proc_name->backend_decl
= build_decl (ns->proc_name->declared_at.lb->location,
NAMESPACE_DECL, get_identifier (ns->proc_name->name),
void_type_node);
[...]
for (n = ns->contained; n; n = n->sibling)
{
gfc_create_function_decl (n, false);
DECL_CONTEXT (n->proc_name->backend_decl) =
ns->proc_name->backend_decl;
Thus, I wonder whether this generates them also in global namespace or
not. I think it works for modules (if one follows current_function_decl)
- but does it also work in cases like:
subroutine foo()
type t
procedure(int), pointer :: p => int
end type t
class(t) :: x
...
contains
subroutine int()
end
end
Here, "int" has clearly not global scope. (Side note: I think this is
only valid since F2008 as before internal procedures could not be used
as actual argument due to some issues which also affect proc pointers,
cf. PR which is linked from the wiki's F2008 status page.)
I might miss something, but at least I am not convinced that the code
will be generated in the correct scope. (Actually, in case of such
procedure initializations, it might be that the current scope is the
correct one - if the procedure is in the same scope as the generated
initialization.)
Tobias