+(declaim (ftype (function () (integer 42 42)) bug-655581))
+(defun bug-655581 ()
+ 42)
+(declaim (notinline bug-655581))
+(test-util:with-test (:name :bug-655581)
+ (multiple-value-bind (type derived)
+ (funcall (compile nil `(lambda ()
+ (ctu:compiler-derived-type (bug-655581)))))
+ (assert derived)
+ (assert (equal '(integer 42 42) type))))
+
+(test-util:with-test (:name :clear-derived-types-on-set-fdefn)
+ (let ((*evaluator-mode* :compile)
+ (*derive-function-types* t))
+ (eval `(progn
+ (defun clear-derived-types-on-set-fdefn-1 ()
+ "foo")
+ (setf (symbol-function 'clear-derived-types-on-set-fdefn-1)
+ (constantly "foobar"))
+ (defun clear-derived-types-on-set-fdefn-2 ()
+ (length (clear-derived-types-on-set-fdefn-1)))))
+ (assert (= 6 (clear-derived-types-on-set-fdefn-2)))))
+
+(test-util:with-test (:name (:bug-655126 :derive-function-types t))
+ (let ((*evaluator-mode* :compile)
+ (*derive-function-types* t))
+ (eval `(defun bug-655126 (x) x))
+ ;; Full warnings are ok due to *derive-function-types* = T.
+ (assert (eq :full-warning
+ (handler-case
+ (eval `(defun bug-655126-2 ()
+ (bug-655126)))
+ ((and warning (not style-warning)) ()
+ :full-warning))))
+ (assert (eq 'bug-655126
+ (handler-case
+ (eval `(defun bug-655126 (x y)
+ (cons x y)))
+ ((and warning (not sb-kernel:redefinition-warning)) ()
+ :oops))))
+ (assert (eq :full-warning
+ (handler-case
+ (eval `(defun bug-655126 (x)
+ (bug-655126 x y)))
+ ((and warning
+ (not style-warning)
+ (not sb-kernel:redefinition-warning)) ()
+ :full-warning))))))
+
+(test-util:with-test (:name (:bug-655126 :derive-function-types nil))
+ (let ((*evaluator-mode* :compile))
+ (eval `(defun bug-655126/b (x) x))
+ ;; Just style-warning here.
+ (assert (eq :style-warning
+ (handler-case
+ (eval `(defun bug-655126-2/b ()
+ (bug-655126/b)))
+ (style-warning ()
+ :style-warning))))
+ (assert (eq 'bug-655126/b
+ (handler-case
+ (eval `(defun bug-655126/b (x y)
+ (cons x y)))
+ ((and warning (not sb-kernel:redefinition-warning)) ()
+ :oops))))
+ ;; Bogus self-call is always worth a full one.
+ (assert (eq :full-warning
+ (handler-case
+ (eval `(defun bug-655126/b (x)
+ (bug-655126/b x y)))
+ ((and warning
+ (not style-warning)
+ (not sb-kernel:redefinition-warning)) ()
+ :full-warning))))))
+
+(test-util:with-test (:name :bug-657499)
+ ;; Don't trust derived types within the compilation unit.
+ (ctu:file-compile
+ `((declaim (optimize safety))
+ (defun bug-657499-foo ()
+ (cons t t))
+ (defun bug-657499-bar ()
+ (let ((cons (bug-657499-foo)))
+ (setf (car cons) 3)
+ cons)))
+ :load t)
+ (locally (declare (optimize safety))
+ (setf (symbol-function 'bug-657499-foo) (constantly "foobar"))
+ (assert (eq :type-error
+ (handler-case
+ (funcall 'bug-657499-bar)
+ (type-error (e)
+ (assert (eq 'cons (type-error-expected-type e)))
+ (assert (equal "foobar" (type-error-datum e)))
+ :type-error))))))
+
+(declaim (unsigned-byte *symbol-value-test-var*))
+(defvar *symbol-value-test-var*)
+
+(declaim (unsigned-byte **global-symbol-value-test-var**))
+(defglobal **global-symbol-value-test-var** 0)
+
+(test-util:with-test (:name :symbol-value-type-derivation)
+ (let ((fun (compile
+ nil
+ `(lambda ()
+ *symbol-value-test-var*))))
+ (assert (equal '(function () (values unsigned-byte &optional))
+ (%simple-fun-type fun))))
+ (let ((fun (compile
+ nil
+ `(lambda ()
+ **global-symbol-value-test-var**))))
+ (assert (equal '(function () (values unsigned-byte &optional))
+ (%simple-fun-type fun))))
+ (let ((fun (compile
+ nil
+ `(lambda (*symbol-value-test-var*)
+ (declare (fixnum *symbol-value-test-var*))
+ (symbol-value '*symbol-value-test-var*))))
+ (ufix (type-specifier (specifier-type `(and unsigned-byte fixnum)))))
+ (assert (equal `(function (,ufix) (values ,ufix &optional))
+ (%simple-fun-type fun))))
+ (let ((fun (compile
+ nil
+ `(lambda ()
+ (declare (fixnum **global-symbol-value-test-var**))
+ (symbol-global-value '**global-symbol-value-test-var**))))
+ (ufix (type-specifier (specifier-type `(and unsigned-byte fixnum)))))
+ (assert (equal `(function () (values ,ufix &optional))
+ (%simple-fun-type fun)))))
+
+(test-util:with-test (:name :mv-bind-to-let-type-propagation)
+ (let ((f (compile nil `(lambda (x)
+ (declare (optimize speed)
+ (type (integer 20 50) x))
+ (< (truncate x 10) 1))))
+ (g (compile nil `(lambda (x)
+ (declare (optimize speed)
+ (type (integer 20 50) x))
+ (< (nth-value 1 (truncate x 10)) 10))))
+ (h (compile nil `(lambda (x)
+ (declare (optimize speed)
+ (type (integer 20 50) x))
+ (multiple-value-bind (q r)
+ (truncate x 10)
+ (declare (ignore r))
+ (< q 1)))))
+ (type0 '(function ((integer 20 50)) (values null &optional)))
+ (type1 '(function ((integer 20 50)) (values (member t) &optional))))
+ (assert (equal type0 (sb-kernel:%simple-fun-type f)))
+ (assert (equal type1 (sb-kernel:%simple-fun-type g)))
+ (assert (equal type0 (sb-kernel:%simple-fun-type h)))))
+
+(test-util:with-test (:name :bug-308921)
+ (let ((*check-consistency* t))
+ (ctu:file-compile
+ `((let ((exported-symbols-alist
+ (loop for symbol being the external-symbols of :cl
+ collect (cons symbol
+ (concatenate 'string
+ "#"
+ (string-downcase symbol))))))
+ (defun hyperdoc-lookup (symbol)
+ (cdr (assoc symbol exported-symbols-alist)))))
+ :load nil)))
+
+(test-util:with-test (:name :bug-308941)
+ (multiple-value-bind (warn fail)
+ (let ((*check-consistency* t))
+ (ctu:file-compile
+ "(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defstruct foo3))
+ (defstruct bar
+ (foo #.(make-foo3)))"
+ :load nil))
+ ;; ...but the compiler should not break.
+ (assert (and warn fail))))
+
+(test-util:with-test (:name :bug-903821)
+ (let* ((fun (compile nil '(lambda (x n)
+ (declare (sb-ext:word x)
+ (type (integer 0 #.(1- sb-vm:n-word-bits)) n)
+ (optimize speed))
+ (logandc2 x (ash -1 n)))))
+ (trace-output
+ (with-output-to-string (*trace-output*)
+ (eval `(trace ,(intern (format nil "ASH-LEFT-MOD~D" sb-vm::n-word-bits) "SB-VM")))
+ (assert (= 7 (funcall fun 15 3))))))
+ (assert (string= "" trace-output))))
+
+(test-util:with-test (:name :bug-997528)
+ (let ((fun (compile nil '(lambda (x)
+ (declare (optimize (speed 0) (space 0))
+ (type (integer -228645653448155482 -228645653447928749) x))
+ (floor 1.0 (the (integer -228645653448151677 -228645653448150900) x))))))
+ (multiple-value-bind (quo rem)
+ (funcall fun -228645653448151381)
+ (assert (= quo -1))
+ (assert (= rem (float -228645653448151381))))))
+
+(defmacro def-many-code-constants ()
+ `(defun many-code-constants ()
+ ,@(loop for i from 0 below 1000
+ collect `(print ,(format nil "hi-~d" i)))))
+
+(test-util:with-test (:name :many-code-constants)
+ (def-many-code-constants)
+ (assert (search "hi-999"
+ (with-output-to-string (*standard-output*)
+ (many-code-constants)))))
+
+(test-util:with-test (:name :bug-943953)
+ ;; we sometimes splice compiler structures like clambda in
+ ;; source, and our error reporting would happily use that
+ ;; as source forms.
+ (let* ((src "bug-943953.lisp")
+ (obj (compile-file-pathname src)))
+ (unwind-protect (compile-file src)
+ (ignore-errors (delete-file obj)))))
+
+(declaim (inline vec-1177703))
+(defstruct (vec-1177703 (:constructor vec-1177703 (&optional x)))
+ (x 0.0d0 :type double-float))
+
+(declaim (inline norm-1177703))
+(defun norm-1177703 (v)
+ (vec-1177703 (sqrt (vec-1177703-x v))))
+
+(test-util:with-test (:name :bug-1177703)
+ (compile nil `(lambda (x)
+ (norm-1177703 (vec-1177703 x)))))
+
+(declaim (inline call-1035721))
+(defun call-1035721 (function)
+ (lambda (x)
+ (funcall function x)))
+
+(declaim (inline identity-1035721))
+(defun identity-1035721 (x)
+ x)
+
+(test-util:with-test (:name :bug-1035721)
+ (compile nil `(lambda ()
+ (list
+ (call-1035721 #'identity-1035721)
+ (lambda (x)
+ (identity-1035721 x))))))
+
+(test-util:with-test (:name :expt-type-derivation-and-method-redefinition)
+ (defmethod expt-type-derivation ((x list) &optional (y 0.0))
+ (declare (type float y))
+ (expt 2 y))
+ ;; the redefinition triggers a type lookup of the old
+ ;; fast-method-function's type, which had a bogus type specifier of
+ ;; the form (double-float 0) from EXPT type derivation
+ (defmethod expt-type-derivation ((x list) &optional (y 0.0))
+ (declare (type float y))
+ (expt 2 y)))