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 on 2011-03-29
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
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)

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  Edit
Everyone can see this information.

Other bug subscribers