(assert (eq 'list type))
(assert derivedp)))
+(with-test (:name :rest-list-type-derivation2)
+ (multiple-value-bind (type derivedp)
+ (funcall (funcall (compile nil `(lambda ()
+ (lambda (&rest args)
+ (ctu:compiler-derived-type args))))))
+ (assert (eq 'list type))
+ (assert derivedp)))
+
+(with-test (:name :rest-list-type-derivation3)
+ (multiple-value-bind (type derivedp)
+ (funcall (funcall (compile nil `(lambda ()
+ (lambda (&optional x &rest args)
+ (unless x (error "oops"))
+ (ctu:compiler-derived-type args)))))
+ t)
+ (assert (eq 'list type))
+ (assert derivedp)))
+
+(with-test (:name :rest-list-type-derivation4)
+ (multiple-value-bind (type derivedp)
+ (funcall (funcall (compile nil `(lambda ()
+ (lambda (&optional x &rest args)
+ (declare (type (or null integer) x))
+ (when x (setf args x))
+ (ctu:compiler-derived-type args)))))
+ 42)
+ (assert (equal '(or cons null integer) type))
+ (assert derivedp)))
+
(with-test (:name :base-char-typep-elimination)
(assert (eq (funcall (lambda (ch)
(declare (type base-char ch) (optimize (speed 3) (safety 0)))
(let ((env nil))
(typep x 'fixnum env))))))
(assert (not (ctu:find-named-callees fun)))))
+
+(with-test (:name :bug-309124)
+ (let ((fun
+ (compile nil
+ `(lambda (x)
+ (declare (integer x))
+ (declare (optimize speed))
+ (cond ((typep x 'fixnum)
+ "hala")
+ ((typep x 'fixnum)
+ "buba")
+ ((typep x 'bignum)
+ "hip")
+ (t
+ "zuz"))))))
+ (assert (equal (list "hala" "hip")
+ (sort (ctu:find-code-constants fun :type 'string)
+ #'string<)))))
+
+(with-test (:name :bug-316078)
+ (let ((fun
+ (compile nil
+ `(lambda (x)
+ (declare (type (and simple-bit-vector (satisfies bar)) x)
+ (optimize speed))
+ (elt x 5)))))
+ (assert (not (ctu:find-named-callees fun)))
+ (assert (= 1 (funcall fun #*000001)))
+ (assert (= 0 (funcall fun #*000010)))))
+
+(with-test (:name :mult-by-one-in-float-acc-zero)
+ (assert (eql 1.0 (funcall (compile nil `(lambda (x)
+ (declare (optimize (sb-c::float-accuracy 0)))
+ (* x 1.0)))
+ 1)))
+ (assert (eql -1.0 (funcall (compile nil `(lambda (x)
+ (declare (optimize (sb-c::float-accuracy 0)))
+ (* x -1.0)))
+ 1)))
+ (assert (eql 1.0d0 (funcall (compile nil `(lambda (x)
+ (declare (optimize (sb-c::float-accuracy 0)))
+ (* x 1.0d0)))
+ 1)))
+ (assert (eql -1.0d0 (funcall (compile nil `(lambda (x)
+ (declare (optimize (sb-c::float-accuracy 0)))
+ (* x -1.0d0)))
+ 1))))
+
+(with-test (:name :dotimes-non-integer-counter-value)
+ (assert (raises-error? (dotimes (i 8.6)) type-error)))
+
+(with-test (:name :bug-454681)
+ ;; This used to break due to reference to a dead lambda-var during
+ ;; inline expansion.
+ (assert (compile nil
+ `(lambda ()
+ (multiple-value-bind (iterator+977 getter+978)
+ (does-not-exist-but-does-not-matter)
+ (flet ((iterator+976 ()
+ (funcall iterator+977)))
+ (declare (inline iterator+976))
+ (let ((iterator+976 #'iterator+976))
+ (funcall iterator+976))))))))
+
+(with-test (:name :complex-float-local-fun-args)
+ ;; As of 1.0.27.14, the lambda below failed to compile due to the
+ ;; compiler attempting to pass unboxed complex floats to Z and the
+ ;; MOVE-ARG method not expecting the register being used as a
+ ;; temporary frame pointer. Reported by sykopomp in #lispgames,
+ ;; reduced test case provided by _3b`.
+ (compile nil '(lambda (a)
+ (labels ((z (b c)
+ (declare ((complex double-float) b c))
+ (* b (z b c))))
+ (loop for i below 10 do
+ (setf a (z a a)))))))
+
+(with-test (:name :bug-309130)
+ (assert (eq :warning
+ (handler-case
+ (compile nil `(lambda () (svref (make-array 8 :adjustable t) 1)))
+ ((and warning (not style-warning)) ()
+ :warning))))
+ (assert (eq :warning
+ (handler-case
+ (compile nil `(lambda (x)
+ (declare (optimize (debug 0)))
+ (declare (type vector x))
+ (list (fill-pointer x) (svref x 1))))
+ ((and warning (not style-warning)) ()
+ :warning))))
+ (assert (eq :warning
+ (handler-case
+ (compile nil `(lambda (x)
+ (list (vector-push (svref x 0) x))))
+ ((and warning (not style-warning)) ()
+ :warning))))
+ (assert (eq :warning
+ (handler-case
+ (compile nil `(lambda (x)
+ (list (vector-push-extend (svref x 0) x))))
+ ((and warning (not style-warning)) ()
+ :warning)))))
+
+(with-test (:name :bug-646796)
+ (assert 42
+ (funcall
+ (compile nil
+ `(lambda ()
+ (load-time-value (the (values fixnum) 42)))))))
+
+(with-test (:name :bug-654289)
+ ;; Test that compile-times don't explode when quoted constants
+ ;; get big.
+ (labels ((time-n (n)
+ (let* ((tree (make-tree (expt 10 n) nil))
+ (t0 (get-internal-run-time))
+ (f (compile nil `(lambda (x) (eq x (quote ,tree)))))
+ (t1 (get-internal-run-time)))
+ (assert (funcall f tree))
+ (- t1 t0)))
+ (make-tree (n acc)
+ (cond ((zerop n) acc)
+ (t (make-tree (1- n) (cons acc acc))))))
+ (let* ((times (loop for i from 0 upto 4
+ collect (time-n i)))
+ (max-small (reduce #'max times :end 3))
+ (max-big (reduce #'max times :start 3)))
+ ;; This way is hopefully fairly CPU-performance insensitive.
+ (assert (> (* (+ 2 max-small) 2) max-big)))))
+
+(with-test (:name :bug-309063)
+ (let ((fun (compile nil `(lambda (x)
+ (declare (type (integer 0 0) x))
+ (ash x 100)))))
+ (assert (zerop (funcall fun 0)))))
+
+(with-test (:name :bug-655872)
+ (let ((f (compile nil `(lambda (x)
+ (declare (optimize (safety 3)))
+ (aref (locally (declare (optimize (safety 0)))
+ (coerce x '(simple-vector 128)))
+ 60))))
+ (long (make-array 100 :element-type 'fixnum)))
+ (dotimes (i 100)
+ (setf (aref long i) i))
+ ;; 1. COERCE doesn't check the length in unsafe code.
+ (assert (eql 60 (funcall f long)))
+ ;; 2. The compiler doesn't trust the length from COERCE
+ (assert (eq :caught
+ (handler-case
+ (funcall f (list 1 2 3))
+ (sb-int:invalid-array-index-error (e)
+ (assert (eql 60 (type-error-datum e)))
+ (assert (equal '(integer 0 (3)) (type-error-expected-type e)))
+ :caught))))))
+
+(with-test (:name :bug-655203-regression)
+ (let ((fun (compile nil
+ `(LAMBDA (VARIABLE)
+ (LET ((CONTINUATION
+ (LAMBDA
+ (&OPTIONAL DUMMY &REST OTHER)
+ (DECLARE (IGNORE OTHER))
+ (PRIN1 DUMMY)
+ (PRIN1 VARIABLE))))
+ (FUNCALL CONTINUATION (LIST 1 2)))))))
+ ;; This used to signal a bogus type-error.
+ (assert (equal (with-output-to-string (*standard-output*)
+ (funcall fun t))
+ "(1 2)T"))))
+
+(with-test (:name :constant-concatenate-compile-time)
+ (flet ((make-lambda (n)
+ `(lambda (x)
+ (declare (optimize (speed 3) (space 0)))
+ (concatenate 'string x ,(make-string n)))))
+ (let* ((l0 (make-lambda 1))
+ (l1 (make-lambda 10))
+ (l2 (make-lambda 100))
+ (l3 (make-lambda 1000))
+ (t0 (get-internal-run-time))
+ (f0 (compile nil l0))
+ (t1 (get-internal-run-time))
+ (f1 (compile nil l1))
+ (t2 (get-internal-run-time))
+ (f2 (compile nil l2))
+ (t3 (get-internal-run-time))
+ (f3 (compile nil l3))
+ (t4 (get-internal-run-time))
+ (d0 (- t1 t0))
+ (d1 (- t2 t1))
+ (d2 (- t3 t2))
+ (d3 (- t4 t3))
+ (short-avg (/ (+ d0 d1 d2) 3)))
+ (assert (and f1 f2 f3))
+ (assert (< d3 (* 10 short-avg))))))