get-setf-expansion of CxxR functions is nonconformant

Bug #1450968 reported by Douglas Katzman on 2015-05-02
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Douglas Katzman

Bug Description

Citing http://www.lispworks.com/documentation/HyperSpec/Body/f_car_c.htm

"This place ... Is equivalent to this place ...
(caar x) (car (car x))
(cadr x) (car (cdr x))
..." and so on.

A simple counterexample to the stipulated "equivalence" of places:

* (defun g (x) (rplaca x (cons 111 222)) 100)
* (defun h (x) (rplaca x nil) 10)

* (defun bar (selector)
  (let* ((inner (cons 5 6))
         (cell (list inner)))
    (format t "Cell=~S~%" cell)
    (ecase selector
      (:car-car (incf (car (car cell)) (g cell)))
      (:caar (incf (caar cell) (g cell)))
      (:cdr-car (incf (cdr (car cell)) (h cell)))
      (:cdar (incf (cdar cell) (h cell))))
    (format t "Cell=~S, inner=~S~%" cell inner)
    (values)))

* (bar :car-car)
Cell=((5 . 6))
Cell=((111 . 222)), inner=(105 . 6)
* (bar :caar)
Cell=((5 . 6))
Cell=((211 . 222)), inner=(5 . 6)
* (bar :cdr-car)
Cell=((5 . 6))
Cell=(NIL), inner=(5 . 16)
* (bar :cdar)
Cell=((5 . 6))
debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {1002D5ECB3}>:
  Argument X is not a NUMBER: NIL

The problem is that the setf "getter" for CAAR returns CAAR itself instead of CAR of a temp as required by equivalence to the exploded form of CAR/CDR compositions.
* (macroexpand-1 '(incf (caar x)))
(LET* ((#:G536 X) (#:G537 (+ (CAAR #:G536) 1)))
  (SB-KERNEL:%RPLACA (CAR #:G536) #:G537))

Same is true of FIRST,SECOND,etc and of all R/M/W macros that use get-setf-expansion.

Also I suspect that while our expansion of (PUSHNEW X (NTH I L)) is not non-conformant, it would be a lot nicer if if expanded to something like:
  (let ((cell (nthcdr index list))) (pushnew item (car cell))))
instead of something like:
  (%setnth ... (adjoin ... (nth )))

Douglas Katzman (dougk) on 2015-05-02
Changed in sbcl:
assignee: nobody → Douglas Katzman (dougk)
status: New → In Progress
Douglas Katzman (dougk) on 2015-05-02
Changed in sbcl:
status: In Progress → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers