(compile nil '(lambda (x) (coerce (sqrt x) 'float))) emits WARNING in sbcl 2.1.2
Bug #1920931 reported by
Andrew Berkley
This bug affects 2 people
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
I saw this on irc from etimmons, but no one reported it here, so putting it here just in case this works better.
(lambda (y)
(coerce (sqrt y) 'float))
emits a WARNING
; in: LAMBDA (Y)
; (COERCE (SQRT Y) 'FLOAT)
;
; caught WARNING:
; Derived type of SB-C::X is
; (VALUES (OR (COMPLEX SINGLE-FLOAT) (COMPLEX DOUBLE-FLOAT)) &OPTIONAL),
; conflicting with its asserted type
; REAL.
coerce expands to to
(if (floatp x)
x
(
This warns because we know sqrt returns a float or a complex float. So %single-float is only called if s is complex, which is a code generation failure.
Note that (float (sqrt y)) does not WARN.
description: | updated |
description: | updated |
description: | updated |
description: | updated |
Changed in sbcl: | |
status: | New → Fix Committed |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
To post a comment you must log in.
So far what I have is a change to typetran.lisp line 1211:
((csubtypep tspec (specifier-type 'float)) equal-or- intersect value-type (specifier-type 'float))
x
( if (realp x)
(%single- float x)
(locally (declare (notinline coerce))
(coerce x 'float))))) ;; this will emit an error always
(if (types-
`(the ,tval (if (floatp x)
`(the ,tval (%single-float x))))
The realp check is deleted if it is known that x is real, which is nice.
I don't like how I handle the known error case. I don't like the locally declare notinline thing, but it was a pattern from lower down in the coerce thing. Maybe could emit a check-type-error directly there too. Either way the debugger the user gets refers to "x" which isn't that helpful. Oh well. Anyway, that is not a new problem.