abcl icon indicating copy to clipboard operation
abcl copied to clipboard

`macroexpand-all` and `tagbody` (and a miscompilation bug as well)

Open Gleefre opened this issue 1 year ago • 0 comments

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.

Gleefre avatar Nov 01 '24 01:11 Gleefre