Another stack analysis bug

Bug #1739495 reported by Paul F. Dietz
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
High
Unassigned

Bug Description

(defun f55 ()
  (declare (notinline +))
  (catch
      (+
       (apply #'+
              (let ((*s* nil)) (declare (special *s*)) 1)
              (max (+ 0) 2)
              (list 3)
              ))
    :done))

==>

failed AVER: (SUBSETP SB-C::END SB-C::END-STACK)
[...]
  0: (SB-INT:BUG "~@<failed AVER: ~2I~_~S~:>" (SUBSETP SB-C::END SB-C::END-STACK))
  1: (SB-IMPL::%FAILED-AVER (SUBSETP SB-C::END SB-C::END-STACK))
  2: (SB-C::ORDER-BLOCK-UVL-SETS #<SB-C::CBLOCK 5 :START c1 {1006731083}> #<SB-C::CBLOCK 6 :START c2 {100672C3A3}>)
[...]

Revision history for this message
Stas Boukarev (stassats) wrote :

(defun f55 (z)
  (catch (apply #'+ 1 z)
    :done))

Changed in sbcl:
status: New → Triaged
importance: Undecided → High
Revision history for this message
Alastair Bridgewater (alastair-bridgewater) wrote :

The component from the reduced test case (in comment #1) contains this little gem:

IR1 block 5 start c1
cleanup :BLOCK
start stack: uv25
  1> 45: Z
 46> 47: known combination v27 v45 {derived *}
 48> 49: full mv-combination v23 v25 v47 {derived (VALUES NUMBER &OPTIONAL)}
 50> known combination v12 v19 v49 {derived (VALUES T &OPTIONAL)}
 51> 52: SB-C::%CLEANUP-POINT {GLOBAL-FUNCTION}
 53> known combination v52 {derived (VALUES T &OPTIONAL)}
 54> 55: ':DONE
end stack: uv25 uv55
successors c56
cleanup :CATCH

Note that the mv-combination consumes v25, also known as uv25, yet it is still on the end-stack.

It looks like what we have here is a previously-unknown precondition for STACK analysis, similar to the "DX allocators must end their blocks" constraint. The "full mv-combination" is the APPLY that creates the tag value for CATCH. The "known combination v12 v19 v49" is %CATCH, which is the "mess-up" for the :CATCH cleanup. STACK takes the start-stack of the block that contains the mess-up for a cleanup as being forced live throughout the body of the cleanup, which in this case includes a value that the block itself pops.

START is (uv25). START-STACK is (uv25). END is (uv25 uv55). END-STACK starts as (uv25), has uv25 popped off, and uv55 pushed, making it (uv55). (SUBSETP END END-STACK) is (SUBSETP '(uv25 uv55) '(uv55)) is NIL.

Revision history for this message
Stas Boukarev (stassats) wrote :
Revision history for this message
Stas Boukarev (stassats) wrote :

4b9dec6b5de0aad6d5038fe2810864e58a95a1a8

Changed in sbcl:
status: Triaged → Fix Committed
Stas Boukarev (stassats)
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.