Compile-time function definition/call compatibility checking is misapplied for redefinitions in the presence of forward or self-references with inlining

Bug #745080 reported by Jean-Philippe Paradis
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Triaged
Low
Unassigned

Bug Description

What I do:
;;; Compile a file containing this with slime:
(defun forward-referencing (first)
  (forward-referenced first))

(defun forward-referenced (first)
  (or first (forward-referencing t)))

;;; Now compile these redefinitions:
(defun forward-referencing (first second)
  (forward-referenced first second))

(defun forward-referenced (first second)
  (or first (forward-referencing t second)))

What happens:
A style-warning is issued at the site of the call to forward-referenced:
"The function was called with two arguments, but wants exactly one."

What I expected to happen:
I think this type of error should be delayed until the end of the compilation unit and then "cancelled" if a redefinition that solves the mismatch is found.

Analysis:
I did quite a bit of testing on this. It appears that the problem is due to redefinition + forward or self-references + inlining. As evidence, simply adding (declare (notinline forward-referenced)) before the call to forward-referenced in the second batch (the redefinitions) solves the problem.

At first I thought the problem was that the call to forward-referenced was being inlined before its redefinition was seen, however I tested this assumption by calling forward-referenced with NIL at the REPL after doing these redefinitions (starting with the same definitions as I started with above):

(defun forward-referencing (first)
  (declare (inline forward-referenced)) ;; Even insisting doesn't give me the bad behavior I expected!
  (forward-referenced first))

(defun forward-referenced (first)
  (print first)
  (or first (forward-referencing t)))

-| NIL
-| T
=> T
The result indicates that forward-referencing correctly picked up the new definition.

So, perhaps the machinery that inlines calls and the one that signals warning for apparent definition/call mismatches are distinct and only the latter behaves incorrectly with redefinition + forward or self-reference + inlining?

SBCL version: 1.0.42
uname -a: Linux dynamorph 2.6.32-30-generic #59-Ubuntu SMP Tue Mar 1 21:30:21 UTC 2011 i686 GNU/Linux

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

Tags: compiler-ir1
Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

Not inlining. NOTINLINE is just taken to mean "assume nothing about this", so anything known about the type is ignored.

But yes, in case the problem call isn't _actually_ inlined, it would be nice to shut down these warnings if the compilation unit solves the issues.

Changed in sbcl:
importance: Undecided → Low
status: New → Triaged
tags: added: compiler-ir1
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.