Incorrect assignment with declared types inside a loop

Bug #2012312 reported by Patrick Poitras
6
This bug affects 1 person
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))
               (WHEN (OR (NOT min)
                         (< G641 min))
                 (SETF min G641)))

             (let ((G642 VALUE))
               (when (or (not max)
                         (> G642 max))
                 (setf max G642))))
    (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)
                       (< value min))
               (setf min value))

             (when (or (not max)
                       (> value max))
                 (setf max value)))
    (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))
               (when (or (not max)
                         (> G642 max))
                 (setf max G642))))
    (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

Stas Boukarev (stassats)
Changed in sbcl:
status: New → Confirmed
assignee: nobody → Stas Boukarev (stassats)
Stas Boukarev (stassats)
Changed in sbcl:
status: Confirmed → Fix Committed
assignee: Stas Boukarev (stassats) → nobody
Revision history for this message
xizang (xizang) wrote :

Before modifying the variable, print it first, and the result is correct again, why is this?

(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))
               (WHEN (OR (NOT min)
                         (< G641 min))
  (print min)
                (SETF min G641)))

             (let ((G642 VALUE))
               (when (or (not max)
                         (> G642 max))
   (print max)
                 (setf max G642))))
    (values min max)))

>
13.0
-13.0
3.0
3.0

Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.