named-lambda clobbers type derivation

Bug #1289779 reported by James M. Lawrence
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Medium
Unassigned

Bug Description

(defun foo ()
  99)

(when nil
  (defun foo ()
    :bar))

(defun foo2 ()
  (let ((x (foo)))
    x))

When the above is compiled,

(foo2) ;=> error: The value 99 is not of type (MEMBER :BAR).

FOO derived type: (FUNCTION NIL (VALUES (INTEGER 99 99) &OPTIONAL))
FOO2 derived type: (FUNCTION NIL (VALUES (MEMBER :BAR) &OPTIONAL))

Confirmed on latest 1.1.16.32-eca778f and various versions I tried
back to 1.0.50.

Linux xii 3.2.0-24-generic-pae #39-Ubuntu SMP Mon May 21 18:54:21 UTC
2012 i686 i686 i386 GNU/Linux

(: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-AFTER-XC-CORE
:SB-CORE-COMPRESSION :SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB
:SB-PACKAGE-LOCKS :SB-SOURCE-LOCATIONS :SB-TEST :SB-THREAD :SB-UNICODE
:SB-XREF-FOR-INTERNALS :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)

Tags: compiler-ir1
description: updated
Revision history for this message
Stas Boukarev (stassats) wrote :

The consequences are actually undefined if you modify the function which is called by another function in the same file, but that typecheck is bogus.

Changed in sbcl:
status: New → Invalid
Revision history for this message
Stas Boukarev (stassats) wrote :

You need to declaim it notinline if you wish to redefine it.

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

And such behaviour should probably only happen when there are benefits, like (defun foo2 () (1+ (foo))), where it can get optimized, passing stuff around just adds an unnecessary typecheck.

Revision history for this message
James M. Lawrence (llmjjmll) wrote :

This was whittled down from a bordeaux-threads bug. Please remove the invalid designation. Note the "when nil", which is the fboundp test in bordeaux-threads. The bug is about the failed type derivation.

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

(defun foo () 1)

(defun x ()
  (sb-int:named-lambda foo () :bar))

(defun foo2 ()
  (1+ (foo)))

named-lambda causes the type to get derived.

summary: - Confusion with non-toplevel defun
+ named-lambda clobbers type derivation
Changed in sbcl:
status: Invalid → Triaged
tags: added: compiler-ir1
Changed in sbcl:
importance: Undecided → Low
Revision history for this message
James M. Lawrence (llmjjmll) wrote :

More closely related to the original bordeaux-threads problem is:

(defparameter *foo* 99)
(declaim (inline foo))
(defun foo () *foo*)

(defun x ()
  (sb-int:named-lambda foo () :bar))

(defun foo2 ()
  (let ((z (foo)))
    z))

(foo2) ;=> :BAR

Revision history for this message
James M. Lawrence (llmjjmll) wrote :

... so for an inline function it's the definition that's clobbered, not just the type derivation. To me this is more alarming than a low priority bug, but whatever you decide.

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

The definition is clobbered when it's declared INLINE.

Changed in sbcl:
importance: Low → Medium
Revision history for this message
Douglas Katzman (dougk) wrote :

I don't think this bug is about inline-ness.

(defun defit1 () (defun foo () :bar))
(defun defit2 () (defun foo () :mumble))

* (compile-file "/tmp/foo.lisp")
...
* (sb-int:info :function :type 'foo)
#<SB-KERNEL:FUN-TYPE (FUNCTION NIL (VALUES (MEMBER :MUMBLE) &OPTIONAL))>

The fact that anything happens at all to global information when a non-toplevel named-lambda is processed is weird.
I don't think the compiler is supposed to assume stuff about definitions in the same file when they didn't happen at toplevel.

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

9cb20dfbaa0dc4e1f51c8b4d5ed5601f4482619b

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.

Duplicates of this bug

Other bug subscribers

Remote bug watches

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