Tobias Burnus
2018-10-11 23:16:54 UTC
Next patch, next try âŠ
The problem is the following: We have a use-associated symbol (a
function) â which is once referenced (by use association).
We now declare a same-name function in the 'contains' section.
gfortran now parses the function name, fetches the symbol and reports
that one duplicates the function (gfc_error_now). However, it continues
afterwards and creates a sym_tree in the gfc_current_ns â and duly
increases the sym->refs to 2.
A bit later, the function gets rejected. (Parsing of the formal
arguments fails when setting a attribute of a use-associated symbol, but
I think this doesn't matter. reject_statement() is called, which rolls
back the symbol, but again, I think that doesn't matter â it just makes
some other solutions a tad more difficult.)
Now, the contains namespace is cleaned up: As the function name is in
the namespace's sym_tree, gfc_release_symbol() is invoked.
The symbol itself is not freed (as --refs > 0), but sym->formal_ns is.
(There are some safety nets, like sym->rev == 2 and sym->ns !=
sym->formal_ns, but they don't help.)
Later, the symbol of the parent's namespace is resolved â and this
includes resolving the formal arguments. â And accessing freed memory
might crash gfortran.
As solution, I return early and with an error from get_proc_name(). I
think that's cleaner than waiting longer â and the early return avoids
creating the symbol at the first place. (Otherwise, modifications have
to go beyond rolling back of the symbols; doing refs++ probably helps,
but is rather intransparent.)
Pro of the early return: Avoids accessing already freed memory, might
generate shorter error output as some later fails (like for not being
able to modify attributes of a use-associated symbol) are gone.
Contra: As one returns before entering a procedure, all following lines
are in the outer scope (usually 'contains') and there probably
unexpected. Hence, one might get a bunch of follow-up errors which do
not help.
Build on x86-64 and even more carefully regtested.
OK?
Tobias
The problem is the following: We have a use-associated symbol (a
function) â which is once referenced (by use association).
We now declare a same-name function in the 'contains' section.
gfortran now parses the function name, fetches the symbol and reports
that one duplicates the function (gfc_error_now). However, it continues
afterwards and creates a sym_tree in the gfc_current_ns â and duly
increases the sym->refs to 2.
A bit later, the function gets rejected. (Parsing of the formal
arguments fails when setting a attribute of a use-associated symbol, but
I think this doesn't matter. reject_statement() is called, which rolls
back the symbol, but again, I think that doesn't matter â it just makes
some other solutions a tad more difficult.)
Now, the contains namespace is cleaned up: As the function name is in
the namespace's sym_tree, gfc_release_symbol() is invoked.
The symbol itself is not freed (as --refs > 0), but sym->formal_ns is.
(There are some safety nets, like sym->rev == 2 and sym->ns !=
sym->formal_ns, but they don't help.)
Later, the symbol of the parent's namespace is resolved â and this
includes resolving the formal arguments. â And accessing freed memory
might crash gfortran.
As solution, I return early and with an error from get_proc_name(). I
think that's cleaner than waiting longer â and the early return avoids
creating the symbol at the first place. (Otherwise, modifications have
to go beyond rolling back of the symbols; doing refs++ probably helps,
but is rather intransparent.)
Pro of the early return: Avoids accessing already freed memory, might
generate shorter error output as some later fails (like for not being
able to modify attributes of a use-associated symbol) are gone.
Contra: As one returns before entering a procedure, all following lines
are in the outer scope (usually 'contains') and there probably
unexpected. Hence, one might get a bunch of follow-up errors which do
not help.
Build on x86-64 and even more carefully regtested.
OK?
Tobias