abcl
abcl copied to clipboard
`macroexpand-all` and `tagbody` (and a miscompilation bug as well)
ext:macroexpand-all doesn't "protect" macroexpansion of the macros in tagbody that are integers and thus can become a tag.
(defmacro not-tag () 1514)
(ext:macroexpand-all '(tagbody (not-tag)))
; => (TAGBODY 1514)
CLHS says (https://www.lispworks.com/documentation/HyperSpec/Body/s_tagbod.htm):
If a statement is a macro form and its macro expansion is an atom, that atom is treated as a statement, not a tag.
This means that the expansion of (not-tag) should be "protected" so that it doesn't become a tag, for example with a progn, as ABCL does with symbols:
(defmacro not-tag-good () 'tag)
(ext:macroexpand-all '(tagbody (not-tag-good)))
; => (TAGBODY (PROGN TAG))
This also leads to problems in compiled code:
(defmacro not-tag () 1514)
(defun foo ()
(block nil
(tagbody
(ignore-errors (go 1514))
(return 'good)
(not-tag)
(return 'bad))))
(foo) ; => BAD
Tested on ABCL 1.9.2
(lisp-implementation-version)
; => "1.9.2"
; "OpenJDK_64-Bit_Server_VM-Private_Build-21.0.1+12-Ubuntu-223.04"
; "amd64-Linux-6.2.0-39-generic"
This affects quite a few other implementations, see this table (two last columns): https://plaster.tymoon.eu/view/4637.