inline-expansion and type-inference

Bug #309115 reported by Nikodemus Siivola on 2008-12-17
This bug affects 3 people
Affects Status Importance Assigned to Milestone

Bug Description

  When the compiler inline expands functions, it may be that different
  kinds of return values are generated from different code branches.
  E.g. an inline expansion of POSITION generates integer results
  from one branch, and NIL results from another. When that inline
  expansion is used in a context where only one of those results
  is acceptable, e.g.
    (defun foo (x)
      (aref *a1* (position x *a2*)))
  and the compiler can't prove that the unacceptable branch is
  never taken, then bogus type mismatch warnings can be generated.
  If you need to suppress the type mismatch warnings, you can
  suppress the inline expansion,
    (defun foo (x)
      #+sbcl (declare (notinline position)) ; to suppress bug 117 bogowarnings
      (aref *a1* (position x *a2*)))
  or, sometimes, suppress them by declaring the result to be of an
  appropriate type,
    (defun foo (x)
      (aref *a1* (the integer (position x *a2*))))

  This is not a new compiler problem in 0.7.0, but the new compiler
  transforms for FIND, POSITION, FIND-IF, and POSITION-IF make it
  more conspicuous. If you don't need performance from these functions,
  and the bogus warnings are a nuisance for you, you can return to
  your pre-0.7.0 state of grace with
    #+sbcl (declaim (notinline find position find-if position-if)) ; bug 117..

See also bug #309113:

Changed in sbcl:
importance: Undecided → Medium
status: New → Confirmed
Nikodemus Siivola (nikodemus) wrote :

Bug #309113 is an instance of this, and contains a nice small test-case.

Nikodemus Siivola (nikodemus) wrote :

See also bug 750797.

Paul Khuong (pvk) wrote :

I think most of this bug's instances now emit STYLE-WARNINGs instead of full WARNINGs, if any future reader is confused.

3b (00003b) wrote :

some more possible examples with various warnings/style warnings in 1.2.6 (and 1.2.1)

(declaim (inline foo))
(defun foo (pointer)
  (flet ((pointer-address (ptr)
           (declare (type system-area-pointer ptr))
           (sb-sys:sap-int ptr)))
    (if (sb-sys:system-area-pointer-p pointer)
        (pointer-address pointer)

(defun bar ()
       (foo 0)))

* ; in: DEFUN BAR
; (FOO 0)
; ==>
; Lisp error during constant folding:
; The value 0 is not of type SYSTEM-AREA-POINTER.

(DEFUN foo1 ()
  (let ((type :float))
    (the (unsigned-byte) (IF (KEYWORDP TYPE)
; in: DEFUN FOO1
; 123
; TYPE))
; caught WARNING:
; Derived type of TYPE is
; conflicting with its asserted type
; See also:
; The SBCL Manual, Node "Handling of Types"

(DEFUN foo2 ()
  (let ((type :float))
    (let ((t2 (IF (KEYWORDP TYPE)
      (declare (unsigned-byte t2) (ignore t2)))))
; in: DEFUN FOO2
; 123
; ==>
; This is not a UNSIGNED-BYTE:
; See also:
; The SBCL Manual, Node "Handling of Types"

Stas Boukarev (stassats) wrote :

Reduce test case for "The value 0 is not of type SYSTEM-AREA-POINTER."

(declaim (inline foo))
(defun foo (x)
  (flet ((c (ptr)
           (declare (type cons ptr))
           (car ptr)))
    (and (consp x)
         (c x))))

(defun bar ()
  (block nil
    (list (lambda () (return)))
    (foo 0)))

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers