% string is list "not \{ a list"
0
% catch {return -code error -errorcode "not \{ a list"} m o
2
% set m
% set o
-errorcode not\ \{\ a\ list -code 1 -level 1
The documentation is clear in
return.n that -errorcode option
takes a list argument.
TclMergeReturnOptions() is failing to
check that.
Tiny attached patch barfs on non-list passed to [return -errorcode].
However, the exact error message is still [return]'s main argument (since it is called with -code error), because the caller of TclProcessReturn sets the interp result later.
Maybe some kind of signalling should be devised to tell it about this special situation.
A simple way out would be in the non-compiled Tcl_ReturnObjCmd to exchange the two statements:
code = TclProcessReturn(interp, code, level, returnOpts);
if (explicitResult) {
Tcl_SetObjResult(interp, objv[objc-1]);
}
yielding:
if (explicitResult) {
Tcl_SetObjResult(interp, objv[objc-1]);
}
code = TclProcessReturn(interp, code, level, returnOpts);
however, doing the same in INST_RETURN_IMM in TEBC implies setting the result twice in the OK case (since the TOS ends up in the result), and I dare not (speed).
Another option, as suggested before, is to add a high bit to TCL_ERROR, that would be intercepted immediately on return from TclProcessReturn, meaning TCL_ERROR_DURING_RETURN. Ugly too.
Advice ?
As noted in the original report, I think
the place to fix this is in TclMergeReturnOptions(),
not in TclProcessReturn().
D'oh of course :)
Attaching patch, please review.
errorcode check in MergeRetOpts
Thanks for the patch. Committing to 8.5 and HEAD
changing only the SetErrorCode arguments to better
match what's been done before.