This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]