Steel Bank Common Lisp

array-in-bounds-p transform breaks on unknown bounds

Reported by James Kalenius on 2012-09-14
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

Test case by |3b| on #lisp

(defun parse-elem (string position)
  (char string position)
  (array-in-bounds-p string (1+ position))))

The value * is not of type SEQUENCE.
   [Condition of type TYPE-ERROR]

Backtrace:
  0: (SB-KERNEL:%MAP NIL #<CLOSURE (LAMBDA # :IN #:BLOCK115077) {C43B52D}> *)[:OPTIONAL]
  1: ((LAMBDA (#:G12) :IN "/home/aeshtaer/code/sbcl/src/cold/compile-cold-sbcl.lisp") #<SB-C::COMBINATION :FUN # :ARGS (# #) {$
  2: (SB-C::IR1-TRANSFORM #<SB-C::COMBINATION :FUN # :ARGS (# #) {C434891}> #<SB-C::TRANSFORM :TYPE #<SB-KERNEL:BUILT-IN-CLASS$
  3: (SB-C::IR1-OPTIMIZE-COMBINATION #<SB-C::COMBINATION :FUN # :ARGS (# #) {C434891}>)
  4: (SB-C::IR1-OPTIMIZE-BLOCK #<SB-C::CBLOCK 4 :START c1 {C433FA1}>)
  5: (SB-C::IR1-OPTIMIZE #<SB-C:COMPONENT :NAME PARSE-ELEM {C4362F1}> NIL)
  6: (SB-C::IR1-OPTIMIZE-UNTIL-DONE #<SB-C:COMPONENT :NAME PARSE-ELEM {C4362F1}>)
  7: (SB-C::IR1-PHASES #<SB-C:COMPONENT :NAME PARSE-ELEM {C4362F1}>)
  8: (SB-C::COMPILE-COMPONENT #<SB-C:COMPONENT :NAME PARSE-ELEM {C4362F1}>)
  9: (SB-C::%COMPILE ..)
 10: ((LAMBDA () :IN SB-C::ACTUALLY-COMPILE))
 11: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN SB-C::%WITH-COMPILATION-UNIT))
 12: ((FLET #:WITHOUT-INTERRUPTS-BODY-90090 :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
 13: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK ..)
 14: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 15: (SB-C::ACTUALLY-COMPILE ..)
 16: (SB-C:COMPILE-IN-LEXENV ..)
 17: (SB-IMPL::%SIMPLE-EVAL ..)
 18: (SB-INT:SIMPLE-EVAL-IN-LEXENV ..)
 19: (SB-INT:SIMPLE-EVAL-IN-LEXENV ..)
 20: (SB-INT:SIMPLE-EVAL-IN-LEXENV ..)
 21: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DEFUN PARSE-ELEM (STRING POSITION) (CHAR STRING POSITION) (ARRAY-IN-BOUNDS-P STRING (1+ PO$
 22: (EVAL (DEFUN PARSE-ELEM (STRING POSITION) (CHAR STRING POSITION) (ARRAY-IN-BOUNDS-P STRING (1+ POSITION))))

*features*
(:SBCL-DEBUG-PRINT-VARIABLE-ALIST :SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO
 :ASDF2 :ASDF :ASDF-UNICODE :ANSI-CL :COMMON-LISP :SBCL :SB-DOC :SB-TEST
 :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL :SB-SOURCE-LOCATIONS
 :IEEE-FLOATING-POINT :OS-PROVIDES-POLL :OS-PROVIDES-GETPROTOBY-R
 :OS-PROVIDES-SUSECONDS-T :OS-PROVIDES-BLKSIZE-T :OS-PROVIDES-PUTWC
 :OS-PROVIDES-DLADDR :OS-PROVIDES-DLOPEN :LITTLE-ENDIAN :LINKAGE-TABLE
 :MULTIPLY-HIGH-VOPS :MEMORY-BARRIER-VOPS :INLINE-CONSTANTS :CYCLE-COUNTER
 :ALIEN-CALLBACKS :STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
 :STACK-ALLOCATABLE-VECTORS :STACK-ALLOCATABLE-CLOSURES :RAW-INSTANCE-INIT-VOPS
 :UNWIND-TO-FRAME-AND-CALL-VOP :COMPARE-AND-SWAP-VOPS :C-STACK-IS-CONTROL-STACK
 :STACK-GROWS-DOWNWARD-NOT-UPWARD :GENCGC :LARGEFILE :SB-FUTEX :SB-THREAD
 :LINUX :ELF :UNIX :X86)

sbcl --version
SBCL 1.0.57.66-5783625

uname -a
Linux Sri2 3.0.0-0300-generic #201107220917 SMP Fri Jul 22 10:10:37 UTC 2011 i686 i686 i386 GNU/Linux

3b (00003b) wrote :

The code that errors was added in 1.0.30.25, which adds a deftransform for ARRAY-IN-BOUNDS-P which breaks when the array type has dimensions = '*. Not sure if that is a problem normally though, since calls to ARRAY-IN-BOUNDS-P seem to be able to infer a number of dimensions from the number of arguments.

The test case doesn't start failing until 1.0.32.31, after which it seems to forget the array dimensions partway through compiling the function.

nixie (onixie) wrote :

The error raises in deftransform array-in-bounds-p is
due to lack of treat for the most generic array type.

(deftransform array-in-bounds-p ((array &rest subscripts))
  (flet (...)
    (block nil
      (let ((dimensions (array-type-dimensions-or-give-up
                                             (lvar-conservative-type array))))

        ;; shell we (give-up) on dimensions '* ?
        ;; (when (eq dimensions '*)
        ;; (give-up)

        ;; shortcut for zero dimensions
        (when (some (lambda (dim)
                      (and (bound-known-p dim) (zerop dim)))
                         dimensions) ;; dimensions may be '* which is not a sequence.
          (return nil))
        ...))))

The conservative type of the string in the #'parse-elem may be (array t *)
according to:

;;; LVAR-CONSERVATIVE-TYPE
;;;
;;; ....
;;;
;;; So, the conservative option is to use the derived type if the leaf has
;;; only a single ref -- in which case there cannot be a prior call that
;;; mutates it. Otherwise we use the declared type or punt to the most general
;;; type we know to be correct for sure.
(defun lvar-conservative-type (lvar)
     ...)

So Is it right to just (give-up) the ir1-transform for array-in-bounds-p under such case?

Nikodemus Siivola (nikodemus) wrote :

Exactly so.

Do you want to send in a patch, or should I just sort this out?

(Ideally we would also like to keep track of known functions which do something nasty to their array arguments, so values that are only involved in known calls to "good" function don't need the conservative type. ...but that's a separate optimization issue.)

Changed in sbcl:
status: New → Triaged
summary: - IR1-time error in compiling
+ array-in-bounds-p transform breaks on unknown bounds
Changed in sbcl:
assignee: nobody → Nikodemus Siivola (nikodemus)
status: Triaged → In Progress
Nikodemus Siivola (nikodemus) wrote :

commit 7374cac4bf6ad3b9f109e4a4d0558325b2cad230
Author: Nikodemus Siivola <email address hidden>
Date: Sun Oct 7 14:12:59 2012 +0300

    teach NODE-CONSERVATIVE-TYPE about union types

      Conservative type of STRING is STRING -- and this makes it so.

      Fixes lp#1050768 (but also future-proof ARRAY-IN-BOUNDS-P against
      '*) explicitly.

Changed in sbcl:
assignee: Nikodemus Siivola (nikodemus) → nobody
status: In Progress → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers