[gnu.emacs.bug] Bug in the byte-compiler

quiroz@cs.rochester.edu (Cesar Quiroz) (04/29/89)

In re:
    Newsgroups: gnu.emacs
    Subject: Why won't the following file byte-compile?
    Message-ID: <MONTNARO.89Apr28093908@sprite.crd.ge.com>
    Date: 28 Apr 89 13:39:08 GMT
    Sender: news@vdsvax.steinmetz.ge.com
    Reply-To: <montanaro@sprite.crd.ge.com> (Skip Montanaro)

Affects 18.52 and 18.54, at least.  May be older.

I just checked to see if I could fix this in cl.el.  The problem
seems to affect the byte-compiler in general, not just cl.el.  

To see this, try to compile:

(defun nothing (x)
  ((lambda (x) x) x))

byte-compile-form will complain on the grounds that

  (lambda (x) x)

is not a symbol.

DIAGNOSIS:

(defun byte-compile-form (form)
  (setq form (macroexpand form byte-compile-macro-environment))
  (cond ((eq form 'nil)
	 (byte-compile-constant form))
	((eq form 't)
	 (byte-compile-constant form))
	((symbolp form)
	 (byte-compile-variable-ref 'byte-varref form))
	((not (consp form))
	 (byte-compile-constant form))
	(t
	 (let ((handler (get (car form) 'byte-compile))) ;;BUG HERE
	   (if handler
	       (funcall handler form)
	     (byte-compile-normal-call form)))))
  (setq byte-compile-maxdepth
	(max byte-compile-maxdepth
	     (setq byte-compile-depth (1+ byte-compile-depth)))))

The bug is trying to get the handler from the car of the form,
before checking if that car is a symbol.  I am not sure how this
sort of call should be compiled, so I prefer to leave to others the
fixing.  I have experimented with this most obvious fix:

(defun byte-compile-form (form)
  (setq form (macroexpand form byte-compile-macro-environment))
  (cond ((eq form 'nil)
	 (byte-compile-constant form))
	((eq form 't)
	 (byte-compile-constant form))
	((symbolp form)
	 (byte-compile-variable-ref 'byte-varref form))
	((not (consp form))
	 (byte-compile-constant form))
	(t
	 (let ((handler (if (symbolp (car form))
                            (get (car form) 'byte-compile))))
	   (if handler
	       (funcall handler form)
	     (byte-compile-normal-call form)))))
  (setq byte-compile-maxdepth
	(max byte-compile-maxdepth
	     (setq byte-compile-depth (1+ byte-compile-depth)))))

and it seems to deal correctly with Skip's and my example, but I
don't guarantee it makes sense.

-- 
                                      Cesar Augusto Quiroz Gonzalez
                                      Department of Computer Science
                                      University of Rochester
                                      Rochester,  NY 14627