Type error in DEFTRANSFORM *: NIL is not of type NUMBER
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Medium
|
Unassigned |
Bug Description
This looks similar to 1716061.
(defun ftest5 ()
(let ((vals '(669124251968))
(lam '(lambda (b)
(declare (type (integer 544930329876 12017151562996) b))
(declare (optimize (debug 1) (safety 0) (space 3) (compilation-speed 0)))
(catch 'ct5
(*
(flet ((%f (&key (x (throw 'ct5 0)))
(the integer x)))
(%f))
b)))))
(apply (compile nil lam) vals)))
(ftest5) ==>
The value
NIL
is not of type
NUMBER
[Condition of type TYPE-ERROR]
Restarts:
0: [ABORT] Exit debugger, returning to top level.
Backtrace:
0: (ABS NIL)
1: ((SB-C:DEFTRANSFORM *) #<SB-C::COMBINATION :FUN #<SB-C::REF :LEAF #<SB-C::GLOBAL-VAR :%SOURCE-NAME * :TYPE #1=#<SB-
2: (SB-C::
3: (SB-C::
4: (SB-C::
Changed in sbcl: | |
status: | Triaged → Fix Committed |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
The general problem here appears to be that the type of a dead lvar can be determined to be something that is not consistent with its value. In this case, the DEFTRANSFORM requires the type be INTEGER, but the value of the lvar is NIL.
Perhaps DEFTRANSFORM should have a consistency check that the type of the value matches? If it does not, the compiler could determine the expression is dead and stop trying to optimize it.
One can construct other examples where this fails. For example, on the FLOOR function:
(defun ftest6 ()
(let ((vals '(1))
(lam '(lambda (b)
(declare (type (integer 0 1000000000) b))
(catch 'ct5
(floor
b
(flet ((%f (&key (x (throw 'ct5 0)))
(the integer x)))
(%f))
)))))
(apply (compile nil lam) vals)))
this leads to the same type error in a DEFTRANSFORM.