+
+(with-test (:name :fill-complex-single-float)
+ (assert (every (lambda (x) (eql x #c(-1.0 -2.0)))
+ (funcall
+ (lambda ()
+ (make-array 2
+ :element-type '(complex single-float)
+ :initial-element #c(-1.0 -2.0)))))))
+
+(with-test (:name :make-array-symbol-as-initial-element)
+ (assert (every (lambda (x) (eq x 'a))
+ (funcall
+ (compile nil
+ `(lambda ()
+ (make-array 12 :initial-element 'a)))))))
+
+;;; This non-minimal test-case catches a nasty error when loading
+;;; inline constants.
+(deftype matrix ()
+ `(simple-array single-float (16)))
+(declaim (ftype (sb-int:sfunction (single-float single-float single-float single-float
+ single-float single-float single-float single-float
+ single-float single-float single-float single-float
+ single-float single-float single-float single-float)
+ matrix)
+ matrix)
+ (inline matrix))
+(defun matrix (m11 m12 m13 m14
+ m21 m22 m23 m24
+ m31 m32 m33 m34
+ m41 m42 m43 m44)
+ (make-array 16
+ :element-type 'single-float
+ :initial-contents (list m11 m21 m31 m41
+ m12 m22 m32 m42
+ m13 m23 m33 m43
+ m14 m24 m34 m44)))
+(declaim (ftype (sb-int:sfunction ((simple-array single-float (3)) single-float) matrix)
+ rotate-around))
+(defun rotate-around (a radians)
+ (let ((c (cos radians))
+ (s (sin radians))
+ ;; The 1.0 here was misloaded on x86-64.
+ (g (- 1.0 (cos radians))))
+ (let* ((x (aref a 0))
+ (y (aref a 1))
+ (z (aref a 2))
+ (gxx (* g x x)) (gxy (* g x y)) (gxz (* g x z))
+ (gyy (* g y y)) (gyz (* g y z)) (gzz (* g z z)))
+ (matrix
+ (+ gxx c) (- gxy (* s z)) (+ gxz (* s y)) 0.0
+ (+ gxy (* s z)) (+ gyy c) (- gyz (* s x)) 0.0
+ (- gxz (* s y)) (+ gyz (* s x)) (+ gzz c) 0.0
+ 0.0 0.0 0.0 1.0))))
+(with-test (:name :regression-1.0.29.54)
+ (assert (every #'=
+ '(-1.0 0.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 0.0 1.0)
+ (rotate-around
+ (make-array 3 :element-type 'single-float) (coerce pi 'single-float))))
+ ;; Same bug manifests in COMPLEX-ATANH as well.
+ (assert (= (atanh #C(-0.7d0 1.1d0)) #C(-0.28715567731069275d0 0.9394245539093365d0))))
+
+(with-test (:name :slot-value-on-structure)
+ (let ((f (compile nil `(lambda (x a b)
+ (declare (something-known-to-be-a-struct x))
+ (setf (slot-value x 'x) a
+ (slot-value x 'y) b)
+ (list (slot-value x 'x)
+ (slot-value x 'y))))))
+ (assert (equal '(#\x #\y)
+ (funcall f
+ (make-something-known-to-be-a-struct :x "X" :y "Y")
+ #\x #\y)))
+ (assert (not (ctu:find-named-callees f)))))
+
+(defclass some-slot-thing ()
+ ((slot :initarg :slot)))
+(with-test (:name :with-slots-the)
+ (let ((x (make-instance 'some-slot-thing :slot "foo")))
+ (with-slots (slot) (the some-slot-thing x)
+ (assert (equal "foo" slot)))))
+
+;;; Missing &REST type in proclamation causing a miscompile.
+(declaim (ftype
+ (function
+ (sequence unsigned-byte
+ &key (:initial-element t) (:initial-contents sequence))
+ (values sequence &optional))
+ bug-458354))
+(defun bug-458354
+ (sequence length
+ &rest keys
+ &key (initial-element nil iep) (initial-contents nil icp))
+ (declare (sb-ext:unmuffle-conditions style-warning))
+ (declare (ignorable keys initial-element iep initial-contents icp))
+ (apply #'sb-sequence:make-sequence-like sequence length keys))
+(with-test (:name :bug-458354)
+ (assert (equalp #((a b) (a b)) (bug-458354 #(1 2) 2 :initial-element '(a b)))))
+
+(with-test (:name :bug-542807)
+ (handler-bind ((style-warning #'error))
+ (eval '(defstruct bug-542807 slot)))
+ (let (conds)
+ (handler-bind ((style-warning (lambda (c)
+ (push c conds))))
+ (eval '(defstruct bug-542807 slot)))
+ (assert (= 1 (length conds)))
+ (assert (typep (car conds) 'sb-kernel::redefinition-with-defun))))
+
+(with-test (:name :defmacro-not-list-lambda-list)
+ (assert (raises-error? (eval `(defmacro ,(gensym) "foo"))
+ type-error)))
+
+(with-test (:name :bug-308951)
+ (let ((x 1))
+ (dotimes (y 10)
+ (let ((y y))
+ (when (funcall (eval #'(lambda (x) (eql x 2))) y)
+ (defun bug-308951-foo (z)
+ (incf x (incf y z))))))
+ (defun bug-308951-bar (z)
+ (bug-308951-foo z)
+ (values x)))
+ (assert (= 4 (bug-308951-bar 1))))
+
+(declaim (inline bug-308914-storage))
+(defun bug-308914-storage (x)
+ (the (simple-array flt (*)) (bug-308914-unknown x)))
+
+(with-test (:name :bug-308914-workaround)
+ ;; This used to hang in ORDER-UVL-SETS.
+ (handler-case
+ (with-timeout 10
+ (compile nil
+ `(lambda (lumps &key cg)
+ (let ((nodes (map 'list (lambda (lump)
+ (bug-308914-storage lump))
+ lumps)))
+ (setf (aref nodes 0) 2)
+ (assert (every #'~= (apply #'concatenate 'list nodes) '(2 3 6 9)))))))
+ (sb-ext:timeout ()
+ (error "Hang in ORDER-UVL-SETS?"))))
+
+(declaim (inline inlined-function-in-source-path))
+(defun inlined-function-in-source-path (x)
+ (+ x x))
+
+(with-test (:name :inlined-function-in-source-path)
+ (let ((output
+ (with-output-to-string (*error-output*)
+ (compile nil `(lambda (x)
+ (declare (optimize speed))
+ (funcall #'inlined-function-in-source-path x))))))
+ ;; We want the name
+ (assert (search "INLINED-FUNCTION-IN-SOURCE-PATH" output))
+ ;; ...not the leaf.
+ (assert (not (search "DEFINED-FUN" output)))))
+
+(defmacro bug-795705 ()
+ t)
+
+(with-test (:name :bug-795705)
+ (assert (macro-function 'bug-795705))
+ (fmakunbound 'bug-795705)
+ (assert (not (macro-function 'bug-795705))))
+
+(with-test (:name (load-time-value :type-derivation))
+ (let ((name 'load-time-value-type-derivation-test))
+ (labels ((funtype (fun)
+ (sb-kernel:type-specifier
+ (sb-kernel:single-value-type
+ (sb-kernel:fun-type-returns
+ (sb-kernel:specifier-type
+ (sb-kernel:%simple-fun-type fun))))))
+ (test (type1 type2 form value-cell-p)
+ (let* ((lambda-form `(lambda ()
+ (load-time-value ,form)))
+ (core-fun (compile nil lambda-form))
+ (core-type (funtype core-fun))
+ (core-cell (ctu:find-value-cell-values core-fun))
+ (defun-form `(defun ,name ()
+ (load-time-value ,form)))
+ (file-fun (progn
+ (ctu:file-compile (list defun-form) :load t)
+ (symbol-function name)))
+ (file-type (funtype file-fun))
+ (file-cell (ctu:find-value-cell-values file-fun)))
+ (if value-cell-p
+ (assert (and core-cell file-cell))
+ (assert (not (or core-cell file-cell))))
+ (unless (subtypep core-type type1)
+ (error "core: wanted ~S, got ~S" type1 core-type))
+ (unless (subtypep file-type type2)
+ (error "file: wanted ~S, got ~S" type2 file-type)))))
+ (let ((* 10))
+ (test '(integer 11 11) 'number
+ '(+ * 1) nil))
+ (let ((* "fooo"))
+ (test '(integer 4 4) 'unsigned-byte
+ '(length *) nil))
+ (test '(integer 10 10) '(integer 10 10) 10 nil)
+ (test 'cons 'cons '(cons t t) t))))
+
+(with-test (:name (load-time-value :errors))
+ (multiple-value-bind (warn fail)
+ (ctu:file-compile
+ `((defvar *load-time-value-error-value* 10)
+ (declaim (fixnum *load-time-value-error-value*))
+ (defun load-time-value-error-test-1 ()
+ (the list (load-time-value *load-time-value-error-value*))))
+ :load t)
+ (assert warn)
+ (assert fail))
+ (handler-case (load-time-value-error-test-1)
+ (type-error (e)
+ (and (eql 10 (type-error-datum e))
+ (eql 'list (type-error-expected-type e)))))
+ (multiple-value-bind (warn2 fail2)
+ (ctu:file-compile
+ `((defun load-time-value-error-test-2 ()
+ (the list (load-time-value 10))))
+ :load t)
+ (assert warn2)
+ (assert fail2))
+ (handler-case (load-time-value-error-test-2)
+ (type-error (e)
+ (and (eql 10 (type-error-datum e))
+ (eql 'list (type-error-expected-type e))))))
+
+;;;; tests for compiler output
+(with-test (:name :unexpected-compiler-output)
+ (let* ((*error-output* (make-string-output-stream))
+ (output (with-output-to-string (*standard-output*)
+ (compile-file "compiler-output-test.lisp"
+ :print nil :verbose nil))))
+ (unless (zerop (length output))
+ (error "Unexpected output: ~S" output))))
+
+(with-test (:name :bug-493380)
+ (flet ((test (forms)
+ (catch 'debug
+ (let ((*debugger-hook* (lambda (condition if)
+ (throw 'debug
+ (if (typep condition 'serious-condition)
+ :debug
+ :oops)))))
+ (multiple-value-bind (warned failed) (ctu:file-compile forms)
+ (when (and warned failed)
+ :failed))))))
+ (assert (eq :failed (test "(defun")))
+ (assert (eq :failed (test "(defun no-pkg::foo ())")))
+ (assert (eq :failed (test "(cl:no-such-sym)")))
+ (assert (eq :failed (test "...")))))
+
+(defun cmacro-signals-error () :fun)
+(define-compiler-macro cmacro-signals-error () (error "oops"))
+
+(with-test (:name :cmacro-signals-error)
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-signals-error)))
+ (assert (and fun warn fail))
+ (assert (eq :fun (funcall fun)))))
+
+(defun cmacro-with-simple-key (&key a)
+ (format nil "fun=~A" a))
+(define-compiler-macro cmacro-with-simple-key (&whole form &key a)
+ (if (constantp a)
+ (format nil "cmacro=~A" (eval a))
+ form))
+
+(with-test (:name (:cmacro-with-simple-key :no-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-simple-key)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "cmacro=NIL" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-simple-key :constant-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-simple-key :a 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "cmacro=42" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-simple-key :variable-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda (x) (cmacro-with-simple-key x 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "fun=42" (funcall fun :a)))))
+
+(defun cmacro-with-nasty-key (&key ((nasty-key var)))
+ (format nil "fun=~A" var))
+(define-compiler-macro cmacro-with-nasty-key (&whole form &key ((nasty-key var)))
+ (if (constantp var)
+ (format nil "cmacro=~A" (eval var))
+ form))
+
+(with-test (:name (:cmacro-with-nasty-key :no-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-nasty-key)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "cmacro=NIL" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-nasty-key :constant-key))
+ ;; This bogosity is thanks to cmacro lambda lists being /macro/ lambda
+ ;; lists.
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-nasty-key 'nasty-key 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "fun=42" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-nasty-key :variable-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda (nasty-key) (cmacro-with-nasty-key nasty-key 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "fun=42" (funcall fun 'nasty-key)))))
+
+(defconstant tricky-key 'tricky-key)
+(defun cmacro-with-tricky-key (&key ((tricky-key var)))
+ (format nil "fun=~A" var))
+(define-compiler-macro cmacro-with-tricky-key (&whole form &key ((tricky-key var)))
+ (if (constantp var)
+ (format nil "cmacro=~A" (eval var))
+ form))
+
+(with-test (:name (:cmacro-with-tricky-key :no-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-tricky-key)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "cmacro=NIL" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-tricky-key :constant-quoted-key))
+ ;; This bogosity is thanks to cmacro lambda lists being /macro/ lambda
+ ;; lists.
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-tricky-key 'tricky-key 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "fun=42" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-tricky-key :constant-unquoted-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda () (cmacro-with-tricky-key tricky-key 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "cmacro=42" (funcall fun)))))
+
+(with-test (:name (:cmacro-with-tricky-key :variable-key))
+ (multiple-value-bind (fun warn fail)
+ (compile nil `(lambda (x) (cmacro-with-tricky-key x 42)))
+ (assert (and (not warn) (not fail)))
+ (assert (string= "fun=42" (funcall fun 'tricky-key)))))
+
+(defun test-function-983 (x) x)
+(define-compiler-macro test-function-983 (x) x)
+
+(with-test (:name :funcall-compiler-macro)
+ (assert
+ (handler-case
+ (and (compile nil
+ `(lambda ()
+ (funcall (function test-function-983 junk) 1)))
+ nil)
+ (sb-c:compiler-error () t))))
+
+(defsetf test-984 %test-984)
+
+(with-test (:name :setf-function-with-setf-expander)
+ (assert
+ (handler-case
+ (and
+ (defun (setf test-984) ())
+ nil)
+ (style-warning () t))))
+
+(with-test (:name :compile-setf-function)
+ (defun (setf compile-setf) ())
+ (assert (equal (compile '(setf compile-setf))
+ '(setf compile-setf))))
+