failed AVER: (SUBSETP END END-STACK)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
High
|
Unassigned |
Bug Description
If a variable which is supposed to be a structure, but might be inferred to be nil (but not actually ever nil at runtime), is declared dynamic-extent, the compiler crashes. This hugely-
;; Minimal example:
(declaim (inline make-a-rec))
(defstruct (my-rec (:constructor make-a-rec (someslot))) someslot)
(defun hairyfun (rec1 rec2)
(declare (ignore rec1 rec2))
;; complicated stuff elided
nil)
(defmacro my-obj (x) `(when ,x (make-a-rec ,x)))
(defun mumble-p (cptr-a cptr-b)
(let ((r8-a (my-obj cptr-a)) (r8-b (my-obj cptr-b)))
(declare (dynamic-extent r8-a r8-b))
(hairyfun r8-a r8-b)))
;; end of example
A few things can workaround the problem for us:
- remove the inline declamation, of course getting "cannot stack allocate", but no crash; or different compiler policy around this code achieves the same thing
- remove the "WHEN" around the object constructor and refactor MUMBLE-P to test whether it should make the objects at all (because in our case HAIRYFUN needs valid objects, so it would be a bug in our code if we ever got there without - however the rest of the scaffolding provided by MY-OBJ is fairly generic and generally useful, so we can't "just" do that)
- assert essentially the same around the invocation of MY-OBJ by writing (let ((r8-a (my-obj (the (not null)
Tested on 2 versions of sbcl:
Pristine sources:
- SBCL 1.0.54.0-185b926 (Darwin dhcp-172-
*features = (:ASDF2 :ASDF :ANSI-CL :COMMON-LISP :SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL :SB-SOURCE-
Customized by cracauer@google
- 1.0.57.
*features* = (:ITA :SB-THREAD :COMPILER-
Changed in sbcl: | |
status: | New → Triaged |
importance: | Undecided → High |
Changed in sbcl: | |
status: | Triaged → Fix Committed |
Changed in sbcl: | |
assignee: | Stas Boukarev (stassats) → nobody |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
Reduced:
(list (list x))
(list (list x)))))
(defun foo (x)
(let ((a (if x
(declare (dynamic-extent a))
(prin1 a)
1))
So, a problem is with IF and nested DXes.