From: Tom Breton <tehom@panix.com>
To: 5728@debbugs.gnu.org
Subject: bug#5728: Byte compile doesn't work right on macro
Date: Mon, 15 Mar 2010 22:25:51 -0400 [thread overview]
Message-ID: <E1NrMTf-0000f5-TZ@localhost> (raw)
When I byte-compile certain code, the results are different than when
it's not byte-compiled. It seems to wrongly merge lists. The one
unusual thing I was doing with the code is using a macro to generate a
call to a ctor (as generated by defstruct)
I have attached two elisp files which demonstrate the buggy behavior.
The first, "byte-compile-bug.el", is meant to be alternately loaded
plain or loaded byte-compiled. The second, "demo-byte-compile-bug.el"
is partly a script which demonstartes that the behavior is indeed
different when byte-compiled, and partly a collection of
(quote-protected) calls to slightly different examples of the bug and
examples of similar code which does not exhibit the bug, all defined
in the first file.
In GNU Emacs 22.2.1 (i486-pc-linux-gnu, X toolkit, Xaw3d scroll bars)
of 2008-11-09 on raven, modified by Debian
Windowing system distributor `The X.Org Foundation', version 11.0.10402000
configured using `configure '--build=i486-linux-gnu' '--host=i486-linux-gnu' '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-pop=yes' '--enable-locallisppath=/etc/emacs22:/etc/emacs:/usr/local/share/emacs/22.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/22.2/site-lisp:/usr/share/emacs/site-lisp:/usr/share/emacs/22.2/leim' '--with-x=yes' '--with-x-toolkit=athena' '--with-toolkit-scroll-bars' 'build_alias=i486-linux-gnu' 'host_alias=i486-linux-gnu' 'CFLAGS=-DDEBIAN -g -O2' 'LDFLAGS=-g' 'CPPFLAGS=''
Important settings:
value of $LC_ALL: nil
value of $LC_COLLATE: nil
value of $LC_CTYPE: nil
value of $LC_MESSAGES: nil
value of $LC_MONETARY: nil
value of $LC_NUMERIC: nil
value of $LC_TIME: nil
value of $LANG: nil
locale-coding-system: nil
default-enable-multibyte-characters: t
Major mode: Lisp Interaction
Minor modes in effect:
tooltip-mode: t
tool-bar-mode: t
mouse-wheel-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
unify-8859-on-encoding-mode: t
utf-translate-cjk-mode: t
auto-compression-mode: t
line-number-mode: t
Recent input:
M-x r e p o <tab> r t <tab> <return>
Recent messages:
("emacs" "-Q")
For information about GNU Emacs and the GNU system, type C-h C-a.
Making completion list...
Loading help-mode...done
Loading emacsbug...
Loading regexp-opt...done
Loading emacsbug...done
next-history-element: Beginning of history; no preceding item
===File ~/projects/elisp/bugs/byte-compile-bug.el============
;;;_ byte-compile-bug.el --- File to reproduce byte-compile bug
;;;_. Headers
;;;_ , Commentary:
;;Bug report by Tom Breton (Tehom)
;; The bug seems to involve:
;; defstruct
;; macro that builds a ctor.
;; a while loop
;; The byte compiler
;;Observe that it occurs only in compiled code.
;;The macro is made by defmacro* but the same occurs with defmacro
;;feeding defun*
;;;_ , Requires
(eval-when-compile (require 'cl))
;;;_. Body
;;;_ , Type
(defstruct (BUG:structure
(:conc-name BUG:structure->)
(:constructor BUG:make-structure))
"An ADT make by defstruct"
edits
a)
;;;_ , BUG:helper
(defun BUG:helper (accessor oobj form)
""
(subst
(list accessor oobj)
'-old-
(copy-tree form)))
(defmacro* BUG:make-form (oobj &key edits a)
"Construct an BUG:structure object adapted from CAND.
Syntax is almost that of a ctor, but in each form, the symbol `-old-'
is replaced by the value of the respective field of OOBJ."
`(BUG:make-structure
:edits
,(BUG:helper
'BUG:structure->edits
oobj
edits)
:a
,(BUG:helper
'BUG:structure->a
oobj
a)))
;;;_ , BUG
(defun BUG (a)
"Contains a bug involving the byte-compiler"
(let
(
(cand
(BUG:make-structure
:edits '()
:a a)))
(catch 'BUG:answer
(while t
(let
(
(a (BUG:structure->a cand)))
(unless a
(throw 'BUG:answer
(reverse
(BUG:structure->edits cand))))
(setq cand
(BUG:make-form cand
:edits
(cons (car a) -old-)
:a
(cdr -old-))))))))
(defun BUG-2 (a)
"Equivalent to BUG except no catch/throw. Still a bug."
(let
( (done nil)
(cand
(BUG:make-structure
:edits '()
:a a)))
(while (not done)
(let
(
(a (BUG:structure->a cand)))
(if a
(setq cand
(BUG:make-form cand
:edits
(cons (car a) -old-)
:a
(cdr -old-)))
(setq done t))))
(reverse
(BUG:structure->edits cand))))
(defun BUG-3 (a)
"Equivalent to BUG. Also buggy, slightly different manifestation.
Slightly different form not involving the second field `a' of BUG:structure."
(let
(
(cand
(BUG:make-structure
:edits '())))
(catch 'BUG:answer
(while t
(unless a
(throw 'BUG:answer
(reverse
(BUG:structure->edits cand))))
(setq cand
(BUG:make-form cand
:edits
(cons (car a) -old-)))
(pop a)))))
(defun BUG-4 (a)
"Equivalent to BUG. Also buggy, slightly different manifestation.
Slightly different form not directly using a while loop."
(let
(
(cand
(BUG:make-structure
:edits '())))
(dotimes (i (length a))
(setq cand
(BUG:make-form cand
:edits
(cons (car a) -old-)))
(pop a))
(reverse
(BUG:structure->edits cand))))
(defun NOBUG (a)
"Equivalent to BUG.
This form extracts elements from list `a' before using them.
No buggy behavior."
(let
(
(cand
(BUG:make-structure
:edits '()
:a a)))
(catch 'BUG:answer
(progn
(dolist (x a)
(setq cand
(BUG:make-form cand
:edits
(cons x -old-)
:a
(cdr -old-))))
(throw 'BUG:answer
(reverse
(BUG:structure->edits cand)))))))
(defun NOBUG-2 (a)
"Equivalent to BUG except doesn't use the second field `a' of
BUG:structure and extracts elements from list `a' before using
them.
No buggy behavior."
(let
(
(cand
(BUG:make-structure
:edits '())))
(catch 'BUG:answer
(while t
(let
((x (pop a)))
(unless x
(throw 'BUG:answer
(reverse
(BUG:structure->edits cand))))
(setq cand
(BUG:make-form cand
:edits
(cons x -old-))))))))
;;;_. Footers
;;;_ , Provides
(provide 'byte-compile-bug)
;;;_ * Local emacs vars.
;;;_ + Local variables:
;;;_ + mode: allout
;;;_ + End:
;;;_ , End
;;; byte-compile-bug.el ends here
============================================================
===File ~/projects/elisp/bugs/demo-byte-compile-bug.el======
;;File to demonstrate this bug. eval-buffer to see it. Also various
;;examples of it are included for easy C-x C-e exploration.
(defun BUG:assert-works-ok (str)
""
(message str)
(assert
(equal
(BUG
'(a b c d))
'(a b c d))
t))
(progn
(load-file "byte-compile+cl.el")
(BUG:assert-works-ok "Uncompiled version works OK")
(byte-compile-file "byte-compile+cl.el")
(load-file "byte-compile+cl.elc")
(BUG:assert-works-ok "Compiled version doesn't"))
;;For comparison:
;;Buggy equivalents
'
(assert
(equal
(BUG-2
'(a b c d))
'(a b c d))
t)
'
(assert
(equal
(BUG-3
'(a b c d))
'(a b c d))
t)
'
(assert
(equal
(BUG-4
'(a b c d))
'(a b c d))
t)
;;Non-buggy equivalents
'
(assert
(equal
(NOBUG
'(a b c d))
'(a b c d))
t)
'
(assert
(equal
(NOBUG-2
'(a b c d))
'(a b c d))
t)============================================================
next reply other threads:[~2010-03-16 2:25 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-16 2:25 Tom Breton [this message]
2010-04-08 20:02 ` bug#5728: Byte compile doesn't work right on macro Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1NrMTf-0000f5-TZ@localhost \
--to=tehom@panix.com \
--cc=5728@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).