;;;; absolutely no warranty. See the COPYING and CREDITS files for
;;;; more information.
+(cl:in-package :sb-c)
+
+(defknown compiler-derived-type (t) (values t t) (movable flushable unsafe))
+
+(deftransform compiler-derived-type ((x))
+ `(values ',(type-specifier (lvar-type x)) t))
+
+(defun compiler-derived-type (x)
+ (values t nil))
+
(cl:in-package :cl-user)
;; The tests in this file assume that EVAL will use the compiler
(type (member ,x #:g5437 char-code #:g5438) p2))
(* 104102267 p2))))
(floatp (funcall (compile nil form) x))))
+
+;;; misc.622
+(assert (eql
+ (funcall
+ (compile
+ nil
+ '(lambda (p2)
+ (declare (optimize (speed 3) (safety 2) (debug 3) (space 0))
+ (type real p2))
+ (+ 81535869 (the (member 17549.955 #:g35917) p2))))
+ 17549.955)
+ (+ 81535869 17549.955)))
+
+;;; misc.654
+(assert (eql 2
+ (let ((form '(lambda (p2)
+ (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+ (type (member integer eql) p2))
+ (coerce 2 p2))))
+ (funcall (compile nil form) 'integer))))
+
+;;; misc.656
+(assert (eql 2
+ (let ((form '(lambda (p2)
+ (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+ (type (member integer mod) p2))
+ (coerce 2 p2))))
+ (funcall (compile nil form) 'integer))))
+
+;;; misc.657
+(assert (eql 2
+ (let ((form '(lambda (p2)
+ (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+ (type (member integer values) p2))
+ (coerce 2 p2))))
+ (funcall (compile nil form) 'integer))))
+
+(with-test (:name :string-aref-type)
+ (assert (eq 'character
+ (funcall (compile nil
+ '(lambda (s)
+ (sb-c::compiler-derived-type (aref (the string s) 0))))
+ "foo"))))
+
+(with-test (:name :base-string-aref-type)
+ (assert (eq #+sb-unicode 'base-char
+ #-sb-unicode 'character
+ (funcall (compile nil
+ '(lambda (s)
+ (sb-c::compiler-derived-type (aref (the base-string s) 0))))
+ (coerce "foo" 'base-string)))))
+
+(with-test (:name :dolist-constant-type-derivation)
+ (assert (equal '(integer 1 3)
+ (funcall (compile nil
+ '(lambda (x)
+ (dolist (y '(1 2 3))
+ (when x
+ (return (sb-c::compiler-derived-type y))))))
+ t))))
+
+(with-test (:name :dolist-simple-list-type-derivation)
+ (assert (equal '(integer 1 3)
+ (funcall (compile nil
+ '(lambda (x)
+ (dolist (y (list 1 2 3))
+ (when x
+ (return (sb-c::compiler-derived-type y))))))
+ t))))
+
+(with-test (:name :dolist-dotted-constant-list-type-derivation)
+ (let* ((warned nil)
+ (fun (handler-bind ((style-warning (lambda (c) (push c warned))))
+ (compile nil
+ '(lambda (x)
+ (dolist (y '(1 2 3 . 4) :foo)
+ (when x
+ (return (sb-c::compiler-derived-type y)))))))))
+ (assert (equal '(integer 1 3) (funcall fun t)))
+ (assert (= 1 (length warned)))
+ (multiple-value-bind (res err) (ignore-errors (funcall fun nil))
+ (assert (not res))
+ (assert (typep err 'type-error)))))
+
+(with-test (:name :constant-list-destructuring)
+ (handler-bind ((sb-ext:compiler-note #'error))
+ (progn
+ (assert (= 10
+ (funcall
+ (compile nil
+ '(lambda ()
+ (destructuring-bind (a (b c) d) '(1 (2 3) 4)
+ (+ a b c d)))))))
+ (assert (eq :feh
+ (funcall
+ (compile nil
+ '(lambda (x)
+ (or x
+ (destructuring-bind (a (b c) d) '(1 "foo" 4)
+ (+ a b c d)))))
+ :feh))))))
+
+;;; Functions with non-required arguments used to end up with
+;;; (&OPTIONAL-DISPATCH ...) as their names.
+(with-test (:name :hairy-function-name)
+ (assert (eq 'read-line (nth-value 2 (function-lambda-expression #'read-line))))
+ (assert (equal "#<FUNCTION READ-LINE>" (princ-to-string #'read-line))))
+
+;;; PROGV + RESTRICT-COMPILER-POLICY
+(with-test (:name :progv-and-restrict-compiler-policy)
+ (let ((sb-c::*policy-restrictions* sb-c::*policy-restrictions*))
+ (restrict-compiler-policy 'debug 3)
+ (let ((fun (compile nil '(lambda (x)
+ (let ((i x))
+ (declare (special i))
+ (list i
+ (progv '(i) (list (+ i 1))
+ i)
+ i))))))
+ (assert (equal '(1 2 1) (funcall fun 1))))))