sb-pcl::constructor-function-form calls optimizing-generator even though there are custom methods
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Invalid
|
Undecided
|
Unassigned |
Bug Description
Depending on whether make-instance is specialized on a class object or a class name, the CTOR optimization might or might not be applied. The potential bug could be that the code relies on compute-
This case was described at https:/
First of all, I am not sure the linked example is a conforming program, because I think make-instance is supposed to return an instance of the class, and not an arbitrary value (the glossary entry for direct-instance in the HyperSpec even says that "The function make-instance always returns a direct instance of the class which is (or is named by) its first argument.", but this is just an example and examples are not part of the standard AFAIK).
That being said, there could be conforming program where the return value is an instance but where the around method is not called.
Here is a way to spot the difference:
(defpackage :launchpad-ctor (:use :cl))
(in-package :launchpad-ctor)
(defclass foo () ())
(defclass bar () ())
(defmethod make-instance :around ((o (eql (find-class 'foo))) &key &allow-other-keys) :foo)
(defmethod make-instance :around ((o (eql 'bar)) &key &allow-other-keys) :bar)
(let ((x (make-instance 'foo))
(y (make-instance 'bar)))
(list x y))
;; (:FOO #<BAR {1006DD7403}>)
A little bit of investigation gives:
(defparameter *foo* (SB-PCL:
(defparameter *bar* (SB-PCL:
(setf (sb-pcl::ctor-class *foo*)
(
(setf (sb-pcl::ctor-class *bar*)
(
(sb-pcl:
;; (LAMBDA ()
;; (DECLARE
;; (OPTIMIZE (SPEED 3) (SAFETY 0) (SB-EXT:
;; (MAKE-INSTANCE #<STANDARD-CLASS LAUNCHPAD-
(sb-pcl:
;; (LAMBDA ()
;; (DECLARE
;; (OPTIMIZE (SPEED 3) (SAFETY 0) (SB-EXT:
;; (BLOCK NIL
;; (WHEN (SB-KERNEL:
;; (SB-PCL:
;; (RETURN (FUNCALL #<SB-PCL::CTOR BAR ()>)))
;; (LET ((SB-PCL:
;; (SB-PCL::.SLOTS. (MAKE-ARRAY 0)))
;; (SETF (SB-KERNEL:
;; #<SB-KERNEL:LAYOUT for BAR {2062C803}>)
;; (SETF (SB-PCL:
;; (LET ()
;; (DECLARE (IGNORABLE))
;; (FLET ((SB-PCL:
;; (DECLARE (IGNORE SB-PCL:
;; (LET* ((SB-PCL:
;; SB-PCL:
;; (DECLARE (DYNAMIC-EXTENT (FUNCTION SB-PCL:
;; (LET ((SB-PCL::.II-ARGS. (LIST SB-PCL:
;; (SB-PCL:
;; SB-PCL:
;; NIL
;; NIL
;; T
Adding breaks in CONSTRUCTOR-
(compute-
;; (#<STANDARD-METHOD COMMON-
(compute-
;; (#<STANDARD-METHOD COMMON-
;; #<STANDARD-METHOD COMMON-
By computing the applicable method for a class argument, the function does not see that the called being optimized, which uses a symbol, is going to call other methods, in particular the one that completely discard the instance and returns :BAR.
SBCL 1.4.0.75.
Linux XPS-13-9343 4.4.0-150-generic #176-Ubuntu SMP Wed May 29 18:56:26 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
(:CL-OPENGL-
:CL-JSON-CLOS :CL-JSON :BORDEAUX-THREADS :21BIT-CHARS :FLOAT-QUIET-NAN
:FLOAT-INFINITY :FLEXI-STREAMS :CLOSER-MOP :THREAD-SUPPORT
CFFI-FEATURES:
CFFI-SYS:
:SWANK :QUICKLISP :SB-BSD-
:ASDF2 :ASDF :OS-UNIX :NON-BASE-
:64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
:C-STACK-
:COMPARE-
:FP-AND-
:IMMOBILE-SPACE :INLINE-CONSTANTS :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE
:LINUX :LITTLE-ENDIAN :MEMORY-
:OS-PROVIDES-
:OS-PROVIDES-
:OS-PROVIDES-
:RAW-SIGNED-WORD :RELOCATABLE-HEAP :SB-CORE-
:SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK :SB-SOURCE-
:SB-THREAD :SB-UNICODE :SB-XREF-
:STACK-
:STACK-
:STACK-
:UNDEFINED-
Technically, you're not allowed to do that, according to
http:// www.lispworks. com/documentati on/HyperSpec/ Body/11_ abab.htm
19. Defining a method for a standardized generic function which is applicable when all of the arguments are direct instances of standardized classes.