Subject: bug#46843: 28.0.50; [native-comp] (lambda (x) (if (equal x b) (eq x b) (error ""))) miscompiled

From: Pip Cet <[email-masked]>
Date: Mon, 1 Mar 2021 08:08:42 +0000

On Mon, Mar 1, 2021 at 6:53 AM Pip Cet <[email-masked]> wrote:
>
> In *scratch*, evaluate
>
> (funcall
>  (let* ((lexical-binding t)
>         (a (list 'a))
>         (b (cons a a)))
>    (native-compile
>     `(lambda (x) (if (equal x ',b) (eq x ',b) (error "")))))
>  '((a) a))

The same issue applies to eql. However, I had to convince myself first
that there is valid and useful code that keeps track of the eq-uality
of eql floats. There is, because there might be an eq-based hash table
that uses them.

(funcall
 (let* ((canonical-one 1.0)
        (hash (make-hash-table :test 'eq)))
   (puthash canonical-one t hash)
   (let* ((is-canonical-one
           `(lambda (x) (if (eql x ,canonical-one) (eq x
,canonical-one) (error "")))))
     (setq is-canonical-one (native-compile is-canonical-one))
     `(lambda (x) (if (funcall ',is-canonical-one x) (cl-assert
(gethash x ',hash))))))
 1.0)

is miscompiled to code that causes an assertion violation when it
actually is correct code that verifies, in two different ways, that x
is eq to a canonical float representing 1.0.
Pip