} else /* should this be in unsetparam_pm()? */
Maybe.
I was expecting to find code that clears flags like PM_INTEGER in either bin_unset or in unsetparam_pm but I don't see anything like that. So it's a bit of a mystery to me how and where these flags get cleared and why only PM_NAMEREF needs to be explicitly cleared in bin_unset (or unsetparam_pm).
For code with no errors, clearing PM_NAMEREF in bin_unset seems good enough but there are all these places that check for errors and then sometimes unset a parameter if one was found. These don't go through bin_unset and since you can recover from errors, it might be necessary to push the clearing down to unsetparam_pm. Here is an example that still behaves incorrectly:
() {
typeset -n ref1
typeset -n ref2=ref1
{
ref1=ref2
} always {
TRY_BLOCK_ERROR=0
}
echo REACHED 1
typeset -p ref1
echo REACHED 2
ref1=var
echo REACHED 3
}Output:
REACHED 1
REACHED 2
(anon):11: var: invalid self reference
Strangely enough, if you move everything to the top-level, then it works fine.
It's admittedly a rather convoluted case. Not sure how much we care about such cases.
Philippe