externalizing circular literals doesn't always preserve identity of components

Bug #613905 reported by 3b on 2010-08-05
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Medium
Unassigned

Bug Description

 (eq '#1=(a . #1#) (cdr '(a . #1#)))
 (eq '#1=(a . b) (cdr #2='(#2# . #1#)))

are both T when evaluated, but NIL when COMPILE-FILEd, while 3.2.4.4 says "If two literal objects appearing in the source code for a single file processed with the file compiler are the identical, the corresponding objects in the compiled code must also be the identical."

Changed in sbcl:
status: New → Triaged
importance: Undecided → Medium
Douglas Katzman (dougk) wrote :

This has been fixed. Don't know when.

circ.lisp:
======
;;; The reason for NOTINLINE is that without it, the result would be trivially true
;;; without proving anything about constant dumping.
;;; CDR and EQ are foldable, so F and G would compile down to just the constant T.
(defun f ()
  (declare (notinline eq))
  (eq '#1=(a . #1#) (cdr '(a . #1#))))

(defun g ()
  (declare (notinline eq))
  (eq '#1=(a . b) (cdr #2='(#2# . #1#))))

* (load (compile-file "circ.lisp"))
* (values (f) (g)) => T and T

3b (00003b) wrote :

doesn't seem completely fixed, still happens for top-level forms:

circ.lisp:

(print (eq '#1=(a . #1#) (cdr '(a . #1#))))
(print (eq '#1=(a . b) (cdr #2='(#2# . #1#))))

(defun f ()
  (declare (notinline eq))
  (eq '#1=(a . #1#) (cdr '(a . #1#))))

(defun g ()
  (declare (notinline eq))
  (eq '#1=(a . b) (cdr #2='(#2# . #1#))))

(print (list (f) (g)))

* (load "/tmp/circ.lisp")

T
T
(T T)

* (load (compile-file "/tmp/circ.lisp"))

NIL
NIL
(T T)

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers