Incorrect assignment with declared types inside a loop
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
We have this function that is finding the min and max data points inside a structure.
I've stripped it out to a minimal example on sbcl 2.3.2. The same behavior is observed on a non-minimal example.
==== The example====
(defun minmax-function ()
(let ((min 13d0)
(max -13d0))
(LOOP for iter from 0 below 1
for value of-type double-float = 3d0
do (LET ((G641 VALUE))
(let ((G642 VALUE))
(values min max)))
We would expect min and max to both be 3. Instead, we get min = 3 and max = 13.
If we compile with debug, we get 3 and 3.
I have also verified this example in SBCL 2.2.10, and it does not pose this issue.
I've experimented a bit to find some variants and see if I could cut down the minimal example.
== Variants that are broken on both debug and regular compilation ==
(defun minmax-function ()
(let ((min 13d0)
(max -13d0))
(LOOP for iter from 0 below 1
for value = 3d0
do (when (or (not min)
(when (or (not max)
(values min max)))
== Variants that work on both debug and regular compilation ==
(defun minmax-function ()
(let ((max -13d0))
(LOOP for iter from 0 below 1
for value of-type double-float = 3d0
do
(let ((G642 VALUE))
(values max)))
== Other things ==
Linux <SESSION NAME> 5.15.0-60-generic #66-Ubuntu SMP Fri Jan 20 14:29:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Changed in sbcl: | |
status: | New → Confirmed |
assignee: | nobody → Stas Boukarev (stassats) |
Changed in sbcl: | |
status: | Confirmed → Fix Committed |
assignee: | Stas Boukarev (stassats) → nobody |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
Before modifying the variable, print it first, and the result is correct again, why is this?
(defun minmax-function ()
(WHEN (OR (NOT min)
(< G641 min))
(SETF min G641)))
(let ((min 13d0)
(max -13d0))
(LOOP for iter from 0 below 1
for value of-type double-float = 3d0
do (LET ((G641 VALUE))
(print min)
(let ((G642 VALUE))
(when (or (not max)
(> G642 max))
(setf max G642))))
(print max)
(values min max)))
>
13.0
-13.0
3.0
3.0