Discussion:
[Patch, Fortran] PR58787 ICE (error recovery) in check_proc_interface
Tobias Burnus
2018-10-11 23:16:54 UTC
Permalink
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
Paul Richard Thomas
2018-10-12 06:28:06 UTC
Permalink
Hi Tobias,

This is OK.

Thanks for the patch and the extra careful regtesting :-)

Paul
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
--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein
Loading...