ccl
ccl copied to clipboard
improper insistence on fixnum type
From #ccl on freenode:
(defun bug ()
(let ((indentation 0))
(macrolet ((with-indent (inc &body body)
`(prog2 (incf indentation ,inc)
(progn ,@body)
(decf indentation ,inc))))
(labels ((foo () (1+ indentation)))
(with-indent 2.5 "")))))
Expected result is "". Actual result is an error: "The value 2.5 is not of the expected type FIXNUM".
The labels form seems to be implicated somehow.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
I don't reproduce it on "Version 1.12-dev (v1.12-dev.3-27-g7a42fe0c) Darwinx8664" either with compile-file or load, evaluating the defun in the slime repl, or evaluating (bug) in the three cases.
Still happening to me on macosx, latest everything
Gilbert Baumann wrote on openmcl-devel:
I looked into before-mentioned issue on github. The smallest test case exposing this bug that I could find is like the following:
(DEFUN BUG ()
(DECLARE (OPTIMIZE (SPEED 1) (SAFETY 3) (DEBUG 1) (COMPILATION-SPEED 0)))
(LET ((X 0))
(LABELS ((FOO () (1+ X)))
(SETQ X PI)
(1+ X))))
I get
(bug)
=> #<BOGUS object @ #x302001E0E255>
Which is bad. It goes away with (COMPILATION-SPEED 3). Remove the LABELS and the bug disappears.
I nailed that down to the following change: https://github.com/Clozure/ccl/commit/bed5cf811ae157298903036276c079e336ae1cf9
diff --git a/compiler/nx0.lisp b/compiler/nx0.lisp
index 110c6c41..15101941 100644
--- a/compiler/nx0.lisp
+++ b/compiler/nx0.lisp
@@ -1599,7 +1599,7 @@ Or something. Right? ~s ~s" var varbits))
(with-program-error-handler (lambda (c) (runtime-program-error-form c))
(parse-body (%cddr lambda-form) *nx-lexical-environment* t))
(setf (afunc-acode p) (nx1-lambda (%cadr lambda-form) body decls)))))
-
+ (rewrite-acode-form (afunc-acode p))
(nx1-transitively-punt-bindings *nx-punted-vars*)
(setf (afunc-blocks p) *nx-blocks*)
(setf (afunc-tags p) *nx-tags*)
I suggest until we find the real issue with REWRITE-ACODE-FORM, we disable it, if we can.
A more targeted change would seem to be edit acode-rewrite.lisp and change the definition of acode-rewrite-labels-flet so that it doesn't do any rewriting there.
In other words, do the inverse of
+
(def-acode-rewrite acode-rewrite-labels-flet (labels flet) asserted-type (vars funcs body p2decls)
- (declare (ignore vars funcs))
+ (declare (ignore vars))
+ (dolist (func funcs)
+ (let* ((*nx-current-function* func))
+ (rewrite-acode-form (afunc-acode func))))
(with-acode-declarations p2decls (rewrite-acode-form body asserted-type)))
(which was changed in 3117330ad50003ec2c5923bcb62d84ef4f55acd6)
Source of the problem is this line:
(LET ((X 0))
if this is changed to
(LET ((X 0.0d0))
then everything works fine.
The optimizer is looking at what it thinks the type of X is, which is a fixnum because of that 0, and then compiling a fixnum add/2 instruction, which when handed 1 and PI, creates a bogus object. It's not recognizing that it guessed wrong about the type of X.
When you set (COMPILATION-SPEED 3), this optimization is not done, so everything works.
The bug is somewhere in def-acode-rewrite acode-rewrite-add2.