SB-C::CLAMBDA leaks out when mismatching type of &optional

Bug #943953 reported by Stas Boukarev
42
This bug affects 5 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Medium
Unassigned

Bug Description

Compiling
(defun foo (&optional count)
  (declare (fixnum count))
  count)

results in

attempt to dump invalid structure:
  #<SB-C::CLAMBDA
    :%SOURCE-NAME SB-C::.ANONYMOUS.
    :%DEBUG-NAME (SB-C::HAIRY-ARG-PROCESSOR FOO)
    :KIND :OPTIONAL
    :TYPE #<SB-KERNEL:BUILT-IN-CLASSOID FUNCTION (read-only)>
    :WHERE-FROM :DEFINED
    :VARS (COUNT) {1009C74933}>
How did this happen?

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

Interestingly,

(defun foo (&key count)
  (declare (fixnum count))
  count)

doesn't produce any warnings, although the type mismatch is the same as with &optional.

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

Nor does

(defun foo (&optional x)
  (let ((count x))
    (declare (fixnum count))
    count))

signal any warnings, while

(defun foo ()
  (let (x)
   (let ((count x))
     (declare (fixnum count))
     count)))

does.

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

And

(defun foo (&rest args)
  (declare (cons args))
  args)
doesn't signal, although calling just (foo) will result in a type mismatch.

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

This appears to be a duplicate of https://bugs.launchpad.net/sbcl/+bug/908101 and possibly related to https://bugs.launchpad.net/sbcl/+bug/908102

Revision history for this message
Jan Moringen (scymtym) wrote :

I have probably found another instance of the same problem (sorry if this is unrelated) triggered by COMPILE-FILE on a file containing

(defmethod f ((value string) &key &allow-other-keys)
  (every #'(lambda (code) (<= 0 code 127)) value))

The output is

; compiling file "/tmp/defmethod.lisp" (written 05 NOV 2012 12:07:15 AM):
; compiling (DEFMETHOD F ...)
; file: /tmp/defmethod.lisp
; in: DEFMETHOD F (STRING)
; (<= 0 CODE 127)
; -->
; --> (LAMBDA (#:G5 #:G4 #:G3) (DECLARE (TYPE REAL #:G5 #:G4 #:G3)) (IF (<= #:G5 #:G4) (IF (<= #:G4 #:G3) T NIL) NIL))
; --> SB-C::%FUNCALL
; ==>
; (#<SB-C::CLAMBDA
; :%SOURCE-NAME SB-C::.ANONYMOUS.
; :%DEBUG-NAME (LAMBDA (#:G5 #:G4 #:G3) :IN F)
; :KIND :DELETED
; :TYPE #<SB-KERNEL:BUILT-IN-CLASSOID FUNCTION (read-only)>
; :WHERE-FROM :DEFINED
; :VARS (#:G5 #:G4 #:G3) {AB7ABF9}>
; 0 CODE 127)
;
; caught WARNING:
; Derived type of (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX) is
; (VALUES CHARACTER &OPTIONAL),
; conflicting with its asserted type
; REAL.
; See also:
; The SBCL Manual, Node "Handling of Types"

debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {AB57B49}>:
  attempt to dump invalid structure:
  #<SB-C::CLAMBDA
    :%SOURCE-NAME SB-C::.ANONYMOUS.
    :%DEBUG-NAME (LAMBDA (#:G5 #:G4 #:G3) :IN F)
    :KIND :DELETED
    :TYPE #<SB-KERNEL:BUILT-IN-CLASSOID FUNCTION (read-only)>
    :WHERE-FROM :DEFINED
    :VARS (#:G5 #:G4 #:G3) {AB7ABF9}>
How did this happen?

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Ignore runtime option --eval "(compile-file \"/tmp/defmethod.lisp\")".
  1: [ABORT ] Skip rest of --eval and --load options.
  2: Skip to toplevel READ/EVAL/PRINT loop.
  3: [EXIT ] Exit SBCL (calling #'EXIT, killing the process).

(SB-FASL::DUMP-STRUCTURE
 #<SB-C::CLAMBDA
   :%SOURCE-NAME SB-C::.ANONYMOUS.
   :%DEBUG-NAME (LAMBDA (#:G5 #:G4 #:G3) :IN F)
   :KIND :DELETED
   :TYPE #<SB-KERNEL:BUILT-IN-CLASSOID FUNCTION (read-only)>
   :WHERE-FROM :DEFINED
   :VARS (#:G5 #:G4 #:G3) {AB7ABF9}>
 #<SB-FASL:FASL-OUTPUT "/tmp/defmethod.fasl">)
0]

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

Revision history for this message
Paul Khuong (pvk) wrote :

The attached patch is a simple enough approach to avoid this class of bugs. It might not be ideal for error reporting (I highly doubt the usefulness of only reporting arbitrarily-mangled source), but it's better than nothing.

Revision history for this message
Paul Khuong (pvk) wrote :

Testing more deeply for internal values solves another related bug report.

Changed in sbcl:
assignee: nobody → Paul Khuong (pvk)
status: Confirmed → In Progress
Paul Khuong (pvk)
Changed in sbcl:
status: In Progress → Fix Committed
assignee: Paul Khuong (pvk) → nobody
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.