Remove overly strict proclamation on SB!FASL::COLD-SET
[sbcl.git] / tests / compiler.pure.lisp
blob0f9721fd10d6efd6a92c034d9c6723471a932da8
1 ;;;; various compiler tests without side effects
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; While most of SBCL is derived from the CMU CL system, the test
7 ;;;; files (like this one) were written from scratch after the fork
8 ;;;; from CMU CL.
9 ;;;;
10 ;;;; This software is in the public domain and is provided with
11 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
12 ;;;; more information.
14 (cl:in-package :cl-user)
16 (load "compiler-test-util.lisp")
18 ;; The tests in this file do not work under the legacy interpreter.
19 (when (and (eq sb-ext:*evaluator-mode* :interpret)
20 (not (member :sb-fasteval *features*)))
21 (invoke-restart 'run-tests::skip-file))
23 ;;; Exercise a compiler bug (by crashing the compiler).
24 ;;;
25 ;;; This test code is from Douglas Crosher's simplified TICKLE-BUG
26 ;;; (2000-09-06 on cmucl-imp).
27 ;;;
28 ;;; The bug was fixed by Douglas Crosher's patch, massaged for SBCL by
29 ;;; Martin Atzmueller (2000-09-13 on sbcl-devel).
30 (with-test (:name (:compiler-bug labels tagbody))
31 (funcall (checked-compile
32 `(lambda ()
33 (labels ((fun1 ()
34 (fun2))
35 (fun2 ()
36 (when nil
37 (tagbody
38 tag
39 (fun2)
40 (go tag)))
41 (when nil
42 (tagbody
43 tag
44 (fun1)
45 (go tag)))))
46 (fun1)
47 nil)))))
49 ;;; Exercise a compiler bug (by crashing the compiler).
50 ;;;
51 ;;; Tim Moore gave a patch for this bug in CMU CL 2000-05-24 on
52 ;;; cmucl-imp, and Martin Atzmueller applied it to SBCL.
53 (with-test (:name (:compiler-bug flet inline :undefined-function))
54 (multiple-value-bind (fun failure-p warnings style-warnings)
55 (checked-compile
56 `(lambda (x)
57 (or (integerp x)
58 (block used-by-some-y?
59 (flet ((frob (stk)
60 (dolist (y stk)
61 (unless (rejected? y)
62 (return-from used-by-some-y? t)))))
63 (declare (inline frob))
64 (frob (rstk x))
65 (frob (mrstk x)))
66 nil)))
67 :allow-style-warnings t)
68 (declare (ignore failure-p warnings))
69 (assert (= 3 (length style-warnings)))
70 (funcall fun 13)))
72 ;;; bug 112, reported by Martin Atzmueller 2001-06-25 (originally
73 ;;; from Bruno Haible in CMU CL bugs collection), fixed by
74 ;;; Alexey Dejneka 2002-01-27
75 (assert (= 1 ; (used to give 0 under bug 112)
76 (let ((x 0))
77 (declare (special x))
78 (let ((x 1))
79 (let ((y x))
80 (declare (special x)) y)))))
81 (assert (= 1 ; (used to give 1 even under bug 112, still works after fix)
82 (let ((x 0))
83 (declare (special x))
84 (let ((x 1))
85 (let ((y x) (x 5))
86 (declare (special x)) y)))))
88 ;;; another LET-related bug fixed by Alexey Dejneka at the same
89 ;;; time as bug 112
90 (with-test (:name (let :repeated-name :bug-112))
91 ;; Should complain about duplicate variable names in LET binding
92 (multiple-value-bind (fun failure-p)
93 (checked-compile `(lambda ()
94 (let (x
95 (x 1))
96 (list x)))
97 :allow-failure t)
98 (assert (functionp fun))
99 (assert failure-p)))
101 ;;; bug 169 (reported by Alexey Dejneka 2002-05-12, fixed by David
102 ;;; Lichteblau 2002-05-21)
103 (with-test (:name (let :earmuffs))
104 ;; Compiling this code should cause a STYLE-WARNING about *X*
105 ;; looking like a special variable but not being one.
106 (multiple-value-bind (fun failure-p warnings style-warnings)
107 (checked-compile
108 `(lambda (n)
109 (let ((*x* n))
110 (funcall (symbol-function 'x-getter))
111 (print *x*)))
112 :allow-style-warnings 'sb-kernel:asterisks-around-lexical-variable-name)
113 (declare (ignore failure-p warnings))
114 (assert (functionp fun))
115 (assert (= 1 (length style-warnings))))
116 ;; Compiling this code should not cause a warning (because the
117 ;; DECLARE turns *X* into a special variable as its name suggests it
118 ;; should be).
119 (let ((fun (checked-compile `(lambda (n)
120 (let ((*x* n))
121 (declare (special *x*))
122 (funcall (symbol-function 'x-getter))
123 (print *x*))))))
124 (assert (functionp fun))))
126 ;;; a bug in 0.7.4.11
127 (dolist (i '(a b 1 2 "x" "y"))
128 ;; In sbcl-0.7.4.11, the compiler tried to source-transform the
129 ;; TYPEP here but got confused and died, doing
130 ;; (ASSOC '(AND INTEGERP (SATISFIES PLUSP)))
131 ;; *BACKEND-TYPE-PREDICATES*
132 ;; :TEST #'TYPE=)
133 ;; and blowing up because TYPE= tried to call PLUSP on the
134 ;; characters of the MEMBER-TYPE representing STANDARD-CHAR.
135 (when (typep i '(and integer (satisfies oddp)))
136 (print i)))
137 (dotimes (i 14)
138 (when (typep i '(and integer (satisfies oddp)))
139 (print i)))
141 ;;; bug 156 (reported by APD sbcl-devel 2002-04-12, fixed by CSR patch
142 ;;; sbcl-devel 2002-07-02): FUNCTION-LAMBDA-EXPRESSION of
143 ;;; interactively-compiled functions was broken by sleaziness and
144 ;;; confusion in the assault on 0.7.0, so this expression used to
145 ;;; signal TYPE-ERROR when it found NIL instead of a DEBUG-SOURCE.
146 (eval '(function-lambda-expression #'(lambda (x) x)))
148 ;;; bug caught and fixed by Raymond Toy cmucl-imp 2002-07-10: &REST
149 ;;; variable is not optional.
150 (with-test (:name (:lambda-list &rest :missing-name))
151 (multiple-value-bind (fun failure-p)
152 (checked-compile `(lambda (&rest) 12) :allow-failure t)
153 (assert failure-p)
154 (assert-error (funcall fun))))
156 ;;; on the PPC, we got the magic numbers in undefined_tramp wrong for
157 ;;; a while; fixed by CSR 2002-07-18
158 (with-test (:name :undefined-function-error)
159 (multiple-value-bind (value error)
160 (ignore-errors (some-undefined-function))
161 (assert (null value))
162 (assert (eq (cell-error-name error) 'some-undefined-function))))
164 (with-test (:name :unbound-variable-error)
165 (let ((foo (gensym)))
166 (assert (eq (handler-case (symbol-value foo)
167 (unbound-variable (c) (cell-error-name c)))
168 foo))
169 ;; on x86-64 the code for a literal symbol uses a slightly different path,
170 ;; so test that too
171 (assert (eq (handler-case xyzzy*%state
172 (unbound-variable (c) (cell-error-name c)))
173 'xyzzy*%state))
174 ;; And finally, also on x86-64, there was massive confusion about
175 ;; variable names that looked like names of thread slots.
176 (assert (eq (handler-case *state*
177 (unbound-variable (c) (cell-error-name c)))
178 '*state*))))
180 ;;; Non-symbols shouldn't be allowed as VARs in lambda lists. (Where VAR
181 ;;; is a variable name, as in section 3.4.1 of the ANSI spec.)
182 (with-test (:name (:lambda-list :non-symbols))
183 (mapc (lambda (case)
184 (destructuring-bind (form wrongp) case
185 (multiple-value-bind (fun failure-p)
186 (checked-compile form :allow-failure wrongp)
187 (assert (functionp fun))
188 (when wrongp
189 (assert failure-p)
190 (assert-error (funcall fun))))))
191 '(((lambda ("foo") 12) t)
192 ((lambda (foo) foo) nil)
194 ((lambda (&optional 12) "foo") t)
195 ((lambda (&optional twelve) twelve) nil)
197 ((lambda (&optional (12 12)) "foo") t)
198 ((lambda (&optional (twelve 12)) twelve) nil)
200 ((lambda (&key #\c) "foo") t)
201 ((lambda (&key c) c) nil)
203 ((lambda (&key (#\c #\c)) "foo") t)
204 ((lambda (&key (c #\c)) c) nil)
206 ((lambda (&key ((#\c #\c) #\c)) "foo") t)
207 ((lambda (&key ((:c c-var) #\c)) c-var) nil))))
209 ;;; As reported and fixed by Antonio Martinez-Shotton sbcl-devel
210 ;;; 2002-09-12, this failed in sbcl-0.7.7.23. (with failed AVER
211 ;;; "(LEAF-HAS-SOURCE-NAME-P LEAF)")
212 (assert (= (funcall (eval `(lambda (x) (funcall ,(lambda (y) (+ y 3)) x))) 14)
213 17))
215 ;;; bug 181: bad type specifier dropped compiler into debugger
216 (with-test (:name (compile declare :bad-type-specifier :bug-181))
217 (multiple-value-bind (fun failure-p)
218 (checked-compile `(lambda (x)
219 (declare (type (0) x))
221 :allow-failure t)
222 (assert failure-p)
223 (assert (functionp fun))
224 (assert-error (funcall fun 1))))
226 (with-test (:name (compile make-array :bad-type-specifier :bug-181))
227 (multiple-value-bind (fun failure-p warnings)
228 (checked-compile `(lambda (x)
229 (declare (ignore x))
230 (make-array 1 :element-type '(0)))
231 :allow-warnings t)
232 (declare (ignore failure-p warnings))
233 ;; FIXME (assert (= 1 (length warnings)))
234 (assert (functionp fun))
235 (assert-error (funcall fun 1))))
237 ;;; the following functions must not be flushable
238 (dolist (form '((make-sequence 'fixnum 10)
239 (concatenate 'fixnum nil)
240 (map 'fixnum #'identity nil)
241 (merge 'fixnum nil nil #'<)))
242 (assert (not (eval `(locally (declare (optimize (safety 0)))
243 (ignore-errors (progn ,form t)))))))
245 (dolist (form '((values-list (car (list '(1 . 2))))
246 (fboundp '(set bet))
247 (atan #c(1 1) (car (list #c(2 2))))
248 (nthcdr (car (list (floor (cos 3)))) '(1 2 3 4 5))
249 (nthcdr (car (list 5)) '(1 2 . 3))))
250 (assert (not (eval `(locally (declare (optimize (safety 3)))
251 (ignore-errors (progn ,form t)))))))
253 ;;; feature: we shall complain if functions which are only useful for
254 ;;; their result are called and their result ignored.
255 (with-test (:name :discarded-result)
256 (loop for (form expected-des) in
257 '(((progn (nreverse (list 1 2)) t)
258 "The return value of NREVERSE should not be discarded.")
259 ((progn (nreconc (list 1 2) (list 3 4)) t)
260 "The return value of NRECONC should not be discarded.")
261 ((locally
262 (declare (inline sort))
263 (sort (list 1 2) #'<) t)
264 ;; FIXME: it would be nice if this warned on non-inlined sort
265 ;; but the current simple boolean function attribute
266 ;; can't express the condition that would be required.
267 "The return value of STABLE-SORT-LIST should not be discarded.")
268 ((progn (sort (vector 1 2) #'<) t)
269 ;; Apparently, SBCL (but not CL) guarantees in-place vector
270 ;; sort, so no warning.
271 nil)
272 ((progn (delete 2 (list 1 2)) t)
273 "The return value of DELETE should not be discarded.")
274 ((progn (delete-if #'evenp (list 1 2)) t)
275 ("The return value of DELETE-IF should not be discarded."))
276 ((progn (delete-if #'evenp (vector 1 2)) t)
277 ("The return value of DELETE-IF should not be discarded."))
278 ((progn (delete-if-not #'evenp (list 1 2)) t)
279 "The return value of DELETE-IF-NOT should not be discarded.")
280 ((progn (delete-duplicates (list 1 2)) t)
281 "The return value of DELETE-DUPLICATES should not be discarded.")
282 ((progn (merge 'list (list 1 3) (list 2 4) #'<) t)
283 "The return value of MERGE should not be discarded.")
284 ((progn (nreconc (list 1 3) (list 2 4)) t)
285 "The return value of NRECONC should not be discarded.")
286 ((progn (nunion (list 1 3) (list 2 4)) t)
287 "The return value of NUNION should not be discarded.")
288 ((progn (nintersection (list 1 3) (list 2 4)) t)
289 "The return value of NINTERSECTION should not be discarded.")
290 ((progn (nset-difference (list 1 3) (list 2 4)) t)
291 "The return value of NSET-DIFFERENCE should not be discarded.")
292 ((progn (nset-exclusive-or (list 1 3) (list 2 4)) t)
293 "The return value of NSET-EXCLUSIVE-OR should not be discarded."))
294 for expected = (sb-int:ensure-list expected-des)
296 (multiple-value-bind (fun failure-p warnings style-warnings)
297 (checked-compile `(lambda () ,form) :allow-style-warnings (when expected t))
298 (declare (ignore failure-p warnings))
299 (when expected
300 (assert (= (length expected) (length style-warnings)))
301 (dolist (warning style-warnings)
302 (let ((expect-one (pop expected)))
303 (assert (search expect-one
304 (with-standard-io-syntax
305 (let ((*print-right-margin* nil))
306 (princ-to-string warning))))
308 "~S should have warned ~S, but instead warned: ~A"
309 form expect-one warning))))
310 (assert (functionp fun)))))
312 ;;; a bug in the MAP deftransform caused non-VECTOR array specifiers
313 ;;; to cause errors in the compiler. Fixed by CSR in 0.7.8.10
314 (with-test (:name (map :non-vector))
315 (checked-compile `(lambda (x) (map 'simple-array 'identity x))))
317 ;;; bug 129: insufficient syntax checking in MACROLET
318 (multiple-value-bind (result error)
319 (ignore-errors (eval '(macrolet ((foo x `',x)) (foo 1 2 3))))
320 (assert (null result))
321 (assert (typep error 'error)))
323 ;;; bug 124: environment of MACROLET-introduced macro expanders
324 (assert (equal
325 (macrolet ((mext (x) `(cons :mext ,x)))
326 (macrolet ((mint (y) `'(:mint ,(mext y))))
327 (list (mext '(1 2))
328 (mint (1 2)))))
329 '((:MEXT 1 2) (:MINT (:MEXT 1 2)))))
331 ;;; bug 48c: SYMBOL-MACROLET should signal PROGRAM-ERROR if introduced
332 ;;; symbol is declared to be SPECIAL
333 (multiple-value-bind (result error)
334 (ignore-errors (funcall (lambda ()
335 (symbol-macrolet ((s '(1 2)))
336 (declare (special s))
337 s))))
338 (assert (null result))
339 (assert (typep error 'program-error)))
341 ;;; ECASE should treat a bare T as a literal key
342 (multiple-value-bind (result error)
343 (ignore-errors (ecase 1 (t 0)))
344 (assert (null result))
345 (assert (typep error 'type-error)))
347 (multiple-value-bind (result error)
348 (ignore-errors (ecase 1 (t 0) (1 2)))
349 (assert (eql result 2))
350 (assert (null error)))
352 ;;; FTYPE should accept any functional type specifier
353 (compile nil '(lambda (x) (declare (ftype function f)) (f x)))
355 ;;; FUNCALL of special operators and macros should signal an
356 ;;; UNDEFINED-FUNCTION error
357 ;;; But note the subtle distinction between writing (FUNCALL 'QUOTE 1)
358 ;;; and (FUNCALL #'QUOTE 1). In the latter, the error must be signaled
359 ;;; by the FUNCTION special operator, but the error class is unspecified.
360 (multiple-value-bind (result error)
361 (ignore-errors (funcall 'quote 1))
362 (assert (null result))
363 (assert (typep error 'undefined-function))
364 (assert (eq (cell-error-name error) 'quote)))
365 (multiple-value-bind (result error)
366 (ignore-errors (funcall 'and 1))
367 (assert (null result))
368 (assert (typep error 'undefined-function))
369 (assert (eq (cell-error-name error) 'and)))
371 ;;; PSETQ should behave when given complex symbol-macro arguments
372 (multiple-value-bind (sequence index)
373 (symbol-macrolet ((x (aref a (incf i)))
374 (y (aref a (incf i))))
375 (let ((a (copy-seq #(0 1 2 3 4 5 6 7 8 9)))
376 (i 0))
377 (psetq x (aref a (incf i))
378 y (aref a (incf i)))
379 (values a i)))
380 (assert (equalp sequence #(0 2 2 4 4 5 6 7 8 9)))
381 (assert (= index 4)))
383 (multiple-value-bind (result error)
384 (ignore-errors
385 (let ((x (list 1 2)))
386 (psetq (car x) 3)
388 (assert (null result))
389 (assert (typep error 'program-error)))
391 ;;; COPY-SEQ should work on known-complex vectors:
392 (assert (equalp #(1)
393 (let ((v (make-array 0 :fill-pointer 0)))
394 (vector-push-extend 1 v)
395 (copy-seq v))))
397 ;;; to support INLINE functions inside MACROLET, it is necessary for
398 ;;; FUNCTION-LAMBDA-EXPRESSION to return a proper lambda expression in
399 ;;; certain circumstances, one of which is when compile is called from
400 ;;; top-level.
401 (with-test (:name (compile function-lambda-expression
402 :toplevel :must-return-lambda-expression))
403 (let ((form '(lambda (x) (block nil (print x)))))
404 (assert (equal form (function-lambda-expression
405 (checked-compile form))))))
407 ;;; bug 62: too cautious type inference in a loop
408 (with-test (:name (compile loop :type-inference))
409 (multiple-value-bind (fun failure-p warnings)
410 (checked-compile `(lambda (a)
411 (declare (optimize speed (safety 0)))
412 (typecase a
413 (array (loop (print (car a))))))
414 :allow-failure t
415 :allow-warnings t)
416 (declare (ignore fun))
417 (assert failure-p)
418 (assert (= 1 (length warnings)))))
420 ;;; Bug reported by Robert E. Brown sbcl-devel 2003-02-02: compiler
421 ;;; failure
422 (with-test (:name (:compiler-bug declare type loop))
423 (checked-compile
424 `(lambda (key tree collect-path-p)
425 (let ((lessp (key-lessp tree))
426 (equalp (key-equalp tree)))
427 (declare (type (function (t t) boolean) lessp equalp))
428 (let ((path '(nil)))
429 (loop for node = (root-node tree)
430 then (if (funcall lessp key (node-key node))
431 (left-child node)
432 (right-child node))
433 when (null node)
434 do (return (values nil nil nil))
435 do (when collect-path-p
436 (push node path))
437 (when (funcall equalp key (node-key node))
438 (return (values node path t)))))))
439 :allow-style-warnings t))
441 ;;; CONSTANTLY should return a side-effect-free function (bug caught
442 ;;; by Paul Dietz' test suite)
443 (let ((i 0))
444 (let ((fn (constantly (progn (incf i) 1))))
445 (assert (= i 1))
446 (assert (= (funcall fn) 1))
447 (assert (= i 1))
448 (assert (= (funcall fn) 1))
449 (assert (= i 1))))
451 ;;; Bug 240 reported by tonyms on #lisp IRC 2003-02-25 (modified version)
452 (with-test (:name (:lambda-list &optional :earmuffs))
453 (loop for (form warns-p) in
454 '(((lambda (&optional *x*) *x*) t)
455 ((lambda (&optional *x* &rest y) (values *x* y)) t)
456 ((lambda (&optional *print-length*) (values *print-length*)) nil)
457 ((lambda (&optional *print-length* &rest y) (values *print-length* y)) nil)
458 ((lambda (&optional *x*) (declare (special *x*)) (values *x*)) nil)
459 ((lambda (&optional *x* &rest y) (declare (special *x*)) (values *x* y)) nil))
460 do (let ((style-warnings (nth-value
461 3 (checked-compile
462 form :allow-style-warnings warns-p))))
463 (assert (= (if warns-p 1 0) (length style-warnings))))))
465 ;;; Bug reported by Gilbert Baumann on #lisp IRC 2003-03-26
466 (assert (equal (funcall (eval '(lambda (x &optional (y (pop x))) (list x y)))
467 '(1 2))
468 '((2) 1)))
470 ;;; Bug reported by Paul Dietz on cmucl-imp and fixed by Gerd
471 ;;; Moellmann: CONVERT-MORE-CALL failed on the following call
472 (assert (eq (eval '((lambda (&key) 'u) :allow-other-keys nil)) 'u))
474 (assert-error (multiple-value-bind (a b c)
475 (eval '(truncate 3 4))
476 (declare (integer c))
477 (list a b c))
478 type-error)
480 (assert (equal (multiple-value-list (the (values &rest integer)
481 (eval '(values 3))))
482 '(3)))
484 ;;; Bug relating to confused representation for the wild function
485 ;;; type:
486 (assert (null (funcall (eval '(lambda () (multiple-value-list (values)))))))
488 ;;; &ENVIRONMENT parameter should be bound first (from Paul Dietz'
489 ;;; test suite)
490 (assert (eql (macrolet ((foo () 1))
491 (macrolet ((%f (&optional (x (macroexpand '(foo) env)) &environment env)
493 (%f)))
496 ;;; MACROLET should check for duplicated names
497 (with-test (:name (macrolet :lambda-list :repeated-names))
498 (dolist (ll '((x (z x))
499 (x y &optional z x w)
500 (x y &optional z z)
501 (x &rest x)
502 (x &rest (y x))
503 (x &optional (y nil x))
504 (x &optional (y nil y)) ; TODO this case prints "caught ERROR: ..." but doesn't set failure-p
505 (x &key x)
506 (x &key (y nil x))
507 (&key (y nil z) (z nil w))
508 (&whole x &optional x)))
509 (let ((style-warnings (nth-value
510 3 (checked-compile
511 `(lambda ()
512 (macrolet ((foo ,ll nil)
513 (bar (&environment env)
514 `',(macro-function 'foo env)))
515 (bar)))
516 ;; FIXME :allow-failure is for the annotated case above
517 :allow-failure t :allow-style-warnings t))))
518 (assert style-warnings))))
520 ;; Uh, this test is semi-bogus - it's trying to test that you can't
521 ;; repeat, but it's now actually testing that &WHOLE has to appear
522 ;; first, per the formal spec.
523 (with-test (:name (macrolet :lambda-list &whole :must-be-first))
524 (assert-error (checked-compile
525 `(lambda ()
526 (macrolet ((foo (&environment x &whole x) nil)
527 (bar (&environment env)
528 `',(macro-function 'foo env)))
529 (bar))))))
531 (assert (typep (eval `(the arithmetic-error
532 ',(make-condition 'arithmetic-error)))
533 'arithmetic-error))
535 (with-test (:name (compile make-array :dimensions nil))
536 (checked-compile `(lambda ()
537 (make-array nil :initial-element 11))))
539 (assert-error (funcall (eval #'open) "assertoid.lisp"
540 :external-format '#:nonsense))
541 (assert-error (funcall (eval #'load) "assertoid.lisp"
542 :external-format '#:nonsense))
544 (assert (= (the (values integer symbol) (values 1 'foo 13)) 1))
546 (let ((f (compile nil
547 '(lambda (v)
548 (declare (optimize (safety 3)))
549 (list (the fixnum (the (real 0) (eval v))))))))
550 (assert-error (funcall f 0.1) type-error)
551 (assert-error (funcall f -1) type-error))
553 ;;; the implicit block does not enclose lambda list
554 (with-test (:name (compile :implicit block :does-not-enclose :lambda-list))
555 (let ((forms '((defmacro #1=#:foo (&optional (x (return-from #1#)))
556 (declare (ignore x)))
557 #+nil(macrolet ((#2=#:foo (&optional (x (return-from #2#))))))
558 (define-compiler-macro #3=#:foo (&optional (x (return-from #3#)))
559 (declare (ignore x)))
560 (deftype #4=#:foo (&optional (x (return-from #4#)))
561 (declare (ignore x)))
562 (define-setf-expander #5=#:foo (&optional (x (return-from #5#)))
563 (declare (ignore x)))
564 (defsetf #6=#:foo (&optional (x (return-from #6#))) ()
565 (declare (ignore x))))))
566 (dolist (form forms)
567 (assert (nth-value
568 1 (checked-compile `(lambda () ,form) :allow-failure t))))))
570 (with-test (:name (compile make-array svref :derive-type))
571 (multiple-value-bind (fun failurep warnings)
572 (checked-compile `(lambda ()
573 (svref (make-array '(8 9) :adjustable t) 1))
574 :allow-warnings t)
575 (declare (ignore fun))
576 (assert failurep)
577 (assert (= 1 (length warnings)))))
579 ;;; CHAR= did not check types of its arguments (reported by Adam Warner)
580 (macrolet ((define-char=-test (function form)
581 `(with-test (:name (compile ,function :argument-type-check))
582 (assert-error (funcall (checked-compile ,form) #\a #\b nil)
583 type-error))))
584 (define-char=-test char= `(lambda (x y z) (char= x y z)))
585 (define-char=-test char/= `(lambda (x y z)
586 (declare (optimize (speed 3) (safety 3)))
587 (char/= x y z))))
589 ;;; Compiler lost return type of MAPCAR and friends
590 (with-test (:name (compile mapcar mapc maplist mapl
591 :return-type :type-derivation))
592 (dolist (fun '(mapcar mapc maplist mapl))
593 (assert (= 1 (length (nth-value
594 2 (checked-compile
595 `(lambda (x)
596 (1+ (,fun #'print x)))
597 :allow-warnings t))))))
599 (assert (= 1 (length (nth-value
600 2 (checked-compile
601 `(lambda ()
602 (declare (notinline mapcar))
603 (1+ (mapcar #'print '(1 2 3))))
604 :allow-warnings t))))))
606 ;;; bug found by Paul Dietz: (SETF AREF) for bit vectors with constant
607 ;;; index was effectless
608 (with-test (:name (compile setf aref bit-vector))
609 (let ((f (checked-compile `(lambda (a v)
610 (declare (type simple-bit-vector a) (type bit v))
611 (declare (optimize (speed 3) (safety 0)))
612 (setf (aref a 0) v)
613 a))))
614 (let ((y (make-array 2 :element-type 'bit :initial-element 0)))
615 (assert (equal y #*00))
616 (funcall f y 1)
617 (assert (equal y #*10)))))
619 ;;; use of declared array types
620 (with-test (:name (compile declare array type :no sb-ext:compiler-note))
621 (dolist (form `((lambda (x)
622 (declare (type (simple-array (simple-string 3) (5)) x)
623 (optimize speed))
624 (aref (aref x 0) 0))
625 (lambda (x)
626 (declare (type (simple-array (simple-array bit (10)) (10)) x)
627 (optimize speed))
628 (1+ (aref (aref x 0) 0)))))
629 (checked-compile form :allow-notes nil)))
631 ;;; compiler failure
632 (with-test (:name (compile typep not member))
633 (let ((f (checked-compile `(lambda (x) (typep x '(not (member 0d0)))))))
634 (assert (funcall f 1d0))))
636 (with-test (:name (compile double-float atan))
637 (checked-compile `(lambda (x)
638 (declare (double-float x))
639 (let ((y (* x pi)))
640 (atan y y)))))
642 ;;; bogus optimization of BIT-NOT
643 (multiple-value-bind (result x)
644 (eval '(let ((x (eval #*1001)))
645 (declare (optimize (speed 2) (space 3))
646 (type (bit-vector) x))
647 (values (bit-not x nil) x)))
648 (assert (equal x #*1001))
649 (assert (equal result #*0110)))
651 ;;; the VECTOR type in CONCATENATE/MERGE/MAKE-SEQUENCE means (VECTOR T).
652 (with-test (:name (compile vector make-sequence sb-ext:compiler-note))
653 (let ((fun (checked-compile
654 `(lambda ()
655 (let ((x (make-sequence 'vector 10 :initial-element 'a)))
656 (setf (aref x 4) 'b)
658 :allow-notes t)))
659 (assert (equalp (funcall fun) #(a a a a b a a a a a)))))
661 ;;; this is not a check for a bug, but rather a test of compiler
662 ;;; quality
663 (with-test (:name (compile integer :type-derivation))
664 (dolist (type '((integer 0 *) ; upper bound
665 (real (-1) *)
666 float ; class
667 (real * (-10)) ; lower bound
669 (assert (= 1 (length (nth-value
670 2 (checked-compile
671 `(lambda (n)
672 (declare (optimize (speed 3) (compilation-speed 0)))
673 (loop for i from 1 to (the (integer -17 10) n) by 2
674 collect (when (> (random 10) 5)
675 (the ,type (- i 11)))))
676 :allow-warnings t)))))))
678 ;;; bug 278b
680 ;;; We suppose that INTEGER arithmetic cannot be efficient, and the
681 ;;; compiler has an optimized VOP for +; so this code should cause an
682 ;;; efficiency note.
683 (with-test (:name (compile integer + sb-ext:compiler-note :bug-278b))
684 (assert (= 1 (length (nth-value
685 4 (checked-compile
686 `(lambda (i)
687 (declare (optimize speed))
688 (declare (type integer i))
689 (+ i 2))))))))
691 ;;; bug 277: IGNORE/IGNORABLE declarations should be acceptable for
692 ;;; symbol macros
693 (with-test (:name (compile symbol-macrolet ignore ignorable :bug-277))
694 (checked-compile `(lambda (u v)
695 (symbol-macrolet ((x u)
696 (y v))
697 (declare (ignore x)
698 (ignorable y))
699 (list u v)))))
701 ;;; bug reported by Paul Dietz: wrong optimizer for (EXPT ... 0)
702 (loop for (x type) in
703 '((14 integer)
704 (14 rational)
705 (-14/3 (rational -8 11))
706 (3s0 short-float)
707 (4f0 single-float)
708 (5d0 double-float)
709 (6l0 long-float)
710 (14 real)
711 (13/2 real)
712 (2s0 real)
713 (2d0 real)
714 (#c(-3 4) (complex fixnum))
715 (#c(-3 4) (complex rational))
716 (#c(-3/7 4) (complex rational))
717 (#c(2s0 3s0) (complex short-float))
718 (#c(2f0 3f0) (complex single-float))
719 (#c(2d0 3d0) (complex double-float))
720 (#c(2l0 3l0) (complex long-float))
721 (#c(2d0 3s0) (complex float))
722 (#c(2 3f0) (complex real))
723 (#c(2 3d0) (complex real))
724 (#c(-3/7 4) (complex real))
725 (#c(-3/7 4) complex)
726 (#c(2 3l0) complex))
727 do (dolist (zero '(0 0s0 0f0 0d0 0l0))
728 (dolist (real-zero (list zero (- zero)))
729 (let* ((src `(lambda (x) (expt (the ,type x) ,real-zero)))
730 (fun (compile nil src))
731 (result (1+ (funcall (eval #'*) x real-zero))))
732 (assert (eql result (funcall fun x)))))))
734 ;;; (SIGNED-BYTE 1) [ returned from the logxor derive-type optimizer ]
735 ;;; wasn't recognized as a good type specifier.
736 (let ((fun (lambda (x y)
737 (declare (type (integer -1 0) x y) (optimize speed))
738 (logxor x y))))
739 (assert (= (funcall fun 0 0) 0))
740 (assert (= (funcall fun 0 -1) -1))
741 (assert (= (funcall fun -1 -1) 0)))
743 ;;; from PFD's torture test, triggering a bug in our effective address
744 ;;; treatment.
745 (with-test (:name (compile declare type logandc1 logandc2))
746 (checked-compile `(lambda (a b)
747 (declare (type (integer 8 22337) b))
748 (logandc2
749 (logandc2
750 (* (logandc1 (max -29303 b) 4) b)
751 (abs (logorc1 (+ (logandc1 -11 b) 2607688420) -31153924)))
752 (logeqv (max a 0) b)))))
754 ;;; Alpha floating point modes weren't being reset after an exception,
755 ;;; leading to an exception on the second compile, below.
756 (with-test (:name (compile :floating-point-mode))
757 (let ((form `(lambda (x y) (declare (type (double-float 0.0d0) x y)) (/ x y))))
758 (checked-compile form)
759 (handler-case (/ 1.0 0.0)
760 ;; provoke an exception
761 (arithmetic-error ()))
762 (checked-compile form)))
764 ;;; bug reported by Paul Dietz: component last block does not have
765 ;;; start ctran
766 (with-test (:name (compile block return-from))
767 (checked-compile `(lambda ()
768 (declare (notinline + logand)
769 (optimize (speed 0)))
770 (logand
771 (block b5
772 (flet ((%f1 ()
773 (return-from b5 -220)))
774 (let ((v7 (%f1)))
775 (+ 359749 35728422))))
776 -24076))))
778 (with-test (:name :ansi-misc.293a)
779 (assert (= (funcall
780 (compile
782 '(lambda (a b c)
783 (declare (optimize (speed 2) (space 3) (safety 1)
784 (debug 2) (compilation-speed 2)))
785 (block b6
786 (multiple-value-prog1
787 0 b 0
788 (catch 'ct7
789 (return-from b6
790 (catch 'ct2
791 (complex (cl::handler-bind nil -254932942) 0))))))))
792 1 2 3)
793 -254932942)))
795 (with-test (:name :ansi-misc.293d)
796 (assert (= (funcall
797 (checked-compile
798 `(lambda ()
799 (declare (optimize (debug 3) (safety 0) (space 2)
800 (compilation-speed 2) (speed 2)))
801 (block b4
802 (multiple-value-prog1
804 (catch 'ct8
805 (return-from b4 (catch 'ct2 (progn (tagbody) 0)))))))))
806 0)))
808 (with-test (:name :ansi-misc.618)
809 (assert (= (funcall
810 (checked-compile
811 `(lambda (c)
812 (declare (optimize (space 0) (compilation-speed 2) (debug 0)
813 (speed 3) (safety 0)))
814 (block b1
815 (ignore-errors
816 (multiple-value-prog1 0
817 (apply (constantly 0)
819 (catch 'ct2 (return-from b1 0))
820 nil))))))
821 -4951)
822 0)))
824 ;;; bug 294 reported by Paul Dietz: miscompilation of REM and MOD
825 (with-test (:name (compile rem :bug-294))
826 (assert (= (funcall (checked-compile
827 `(lambda (b)
828 (declare (optimize (speed 3))
829 (type (integer 2 152044363) b))
830 (rem b (min -16 0))))
831 108251912)
832 8)))
834 (with-test (:name (compile mod :bug-294))
835 (assert (= (funcall (checked-compile
836 `(lambda (c)
837 (declare (optimize (speed 3))
838 (type (integer 23062188 149459656) c))
839 (mod c (min -2 0))))
840 95019853)
841 -1)))
843 ;;; bug reported by Paul Dietz: block splitting inside FLUSH-DEAD-CODE
844 (with-test (:name (compile logeqv rem :dead-code :block-splitting))
845 (checked-compile `(lambda (a b c)
846 (block b6
847 (logeqv (rem c -6758)
848 (rem b (max 44 (return-from b6 a))))))))
850 (with-test (:name (compile block flet :dead-code :block-splitting))
851 (checked-compile `(lambda ()
852 (block nil
853 (flet ((foo (x y) (if (> x y) (print x) (print y))))
854 (foo 1 2)
855 (bar)
856 (foo (return 14) 2))))
857 :allow-style-warnings t))
859 ;;; bug in Alpha backend: not enough sanity checking of arguments to
860 ;;; instructions
861 (assert (= (funcall (compile nil
862 '(lambda (x)
863 (declare (fixnum x))
864 (ash x -257)))
865 1024)
868 ;;; bug found by WHN and pfdietz: compiler failure while referencing
869 ;;; an entry point inside a deleted lambda
870 (with-test (:name (compile :reference-entry-point-in-deleted lambda))
871 (checked-compile
872 `(lambda ()
873 (let (r3533)
874 (flet ((bbfn ()
875 (setf r3533
876 (progn
877 (flet ((truly (fn bbd)
878 (let (r3534)
879 (let ((p3537 nil))
880 (unwind-protect
881 (multiple-value-prog1
882 (progn
883 (setf r3534
884 (progn
885 (bubf bbd t)
886 (flet ((c-3536 ()
887 (funcall fn)))
888 (cdec #'c-3536
889 (vector bbd))))))
890 (setf p3537 t))
891 (unless p3537
892 (error "j"))))
893 r3534))
894 (c (pd) (pdc pd)))
895 (let ((a (smock a))
896 (b (smock b))
897 (b (smock c)))))))))
898 (wum #'bbfn "hc3" (list)))
899 r3533))
900 :allow-failure t :allow-style-warnings t))
902 (with-test (:name (compile flet unwind-protect :dead-code))
903 (checked-compile `(lambda () (flet ((%f () (unwind-protect nil))) nil))))
905 ;;; the strength reduction of constant multiplication used (before
906 ;;; sbcl-0.8.4.x) to lie to the compiler. This meant that, under
907 ;;; certain circumstances, the compiler would derive that a perfectly
908 ;;; reasonable multiplication never returned, causing chaos. Fixed by
909 ;;; explicitly doing modular arithmetic, and relying on the backends
910 ;;; being smart.
911 (assert (= (funcall
912 (compile nil
913 '(lambda (x)
914 (declare (type (integer 178956970 178956970) x)
915 (optimize speed))
916 (* x 24)))
917 178956970)
918 4294967280))
920 ;;; bug in modular arithmetic and type specifiers
921 (assert (= (funcall (compile nil '(lambda (x) (logand x x 0)))
925 ;;; MISC.99 from Paul Dietz' random tester: FAST-ASH-MOD32-C VOP
926 ;;; produced wrong result for shift >=32 on X86
927 (assert (= 0 (funcall
928 (compile nil
929 '(lambda (a)
930 (declare (type (integer 4303063 101130078) a))
931 (mask-field (byte 18 2) (ash a 77))))
932 57132532)))
933 ;;; rewrite the test case to get the unsigned-byte 32/64
934 ;;; implementation even after implementing some modular arithmetic
935 ;;; with signed-byte 30:
936 (assert (= 0 (funcall
937 (compile nil
938 '(lambda (a)
939 (declare (type (integer 4303063 101130078) a))
940 (mask-field (byte 30 2) (ash a 77))))
941 57132532)))
942 (assert (= 0 (funcall
943 (compile nil
944 '(lambda (a)
945 (declare (type (integer 4303063 101130078) a))
946 (mask-field (byte 64 2) (ash a 77))))
947 57132532)))
948 ;;; and a similar test case for the signed masking extension (not the
949 ;;; final interface, so change the call when necessary):
950 (assert (= 0 (funcall
951 (compile nil
952 '(lambda (a)
953 (declare (type (integer 4303063 101130078) a))
954 (sb-c::mask-signed-field 30 (ash a 77))))
955 57132532)))
956 (assert (= 0 (funcall
957 (compile nil
958 '(lambda (a)
959 (declare (type (integer 4303063 101130078) a))
960 (sb-c::mask-signed-field 61 (ash a 77))))
961 57132532)))
963 ;;; MISC.101 and MISC.103: FLUSH-DEST did not mark the USE's block for
964 ;;; type check regeneration
965 (assert (eql (funcall
966 (compile nil '(lambda (a c)
967 (declare (type (integer 185501219873 303014665162) a))
968 (declare (type (integer -160758 255724) c))
969 (declare (optimize (speed 3)))
970 (let ((v8
971 (- -554046873252388011622614991634432
972 (ignore-errors c)
973 (unwind-protect 2791485))))
974 (max (ignore-errors a)
975 (let ((v6 (- v8 (restart-case 980))))
976 (min v8 v6))))))
977 259448422916 173715)
978 259448422916))
979 (assert (eql (funcall
980 (compile nil '(lambda (a b)
981 (min -80
982 (abs
983 (ignore-errors
985 (logeqv b
986 (block b6
987 (return-from b6
988 (load-time-value -6876935))))
989 (if (logbitp 1 a) b (setq a -1522022182249))))))))
990 -1802767029877 -12374959963)
991 -80))
993 ;;; various MISC.*, related to NODEs/LVARs with derived type NIL
994 (assert (eql (funcall (compile nil '(lambda (c)
995 (declare (type (integer -3924 1001809828) c))
996 (declare (optimize (speed 3)))
997 (min 47 (if (ldb-test (byte 2 14) c)
998 -570344431
999 (ignore-errors -732893970)))))
1000 705347625)
1001 -570344431))
1002 (assert (eql (funcall
1003 (compile nil '(lambda (b)
1004 (declare (type (integer -1598566306 2941) b))
1005 (declare (optimize (speed 3)))
1006 (max -148949 (ignore-errors b))))
1009 (assert (eql (funcall
1010 (compile nil '(lambda (b c)
1011 (declare (type (integer -4 -3) c))
1012 (block b7
1013 (flet ((%f1 (f1-1 f1-2 f1-3)
1014 (if (logbitp 0 (return-from b7
1015 (- -815145138 f1-2)))
1016 (return-from b7 -2611670)
1017 99345)))
1018 (let ((v2 (%f1 -2464 (%f1 -1146 c c) -2)))
1019 b)))))
1020 2950453607 -4)
1021 -815145134))
1022 (assert (eql (funcall
1023 (compile nil
1024 '(lambda (b c)
1025 (declare (type (integer -29742055786 23602182204) b))
1026 (declare (type (integer -7409 -2075) c))
1027 (declare (optimize (speed 3)))
1028 (floor
1029 (labels ((%f2 ()
1030 (block b6
1031 (ignore-errors (return-from b6
1032 (if (= c 8) b 82674))))))
1033 (%f2)))))
1034 22992834060 -5833)
1035 82674))
1036 (assert (equal (multiple-value-list
1037 (funcall
1038 (compile nil '(lambda (a)
1039 (declare (type (integer -944 -472) a))
1040 (declare (optimize (speed 3)))
1041 (round
1042 (block b3
1043 (return-from b3
1044 (if (= 55957 a) -117 (ignore-errors
1045 (return-from b3 a))))))))
1046 -589))
1047 '(-589 0)))
1049 ;;; MISC.158
1050 (assert (zerop (funcall
1051 (compile nil
1052 '(lambda (a b c)
1053 (declare (type (integer 79828 2625480458) a))
1054 (declare (type (integer -4363283 8171697) b))
1055 (declare (type (integer -301 0) c))
1056 (if (equal 6392154 (logxor a b))
1057 1706
1058 (let ((v5 (abs c)))
1059 (logand v5
1060 (logior (logandc2 c v5)
1061 (common-lisp:handler-case
1062 (ash a (min 36 22477)))))))))
1063 100000 0 0)))
1065 ;;; MISC.152, 153: deleted code and iteration var type inference
1066 (assert (eql (funcall
1067 (compile nil
1068 '(lambda (a)
1069 (block b5
1070 (let ((v1 (let ((v8 (unwind-protect 9365)))
1071 8862008)))
1073 (return-from b5
1074 (labels ((%f11 (f11-1) f11-1))
1075 (%f11 87246015)))
1076 (return-from b5
1077 (setq v1
1078 (labels ((%f6 (f6-1 f6-2 f6-3) v1))
1079 (dpb (unwind-protect a)
1080 (byte 18 13)
1081 (labels ((%f4 () 27322826))
1082 (%f6 -2 -108626545 (%f4))))))))))))
1084 87246015))
1086 (assert (eql (funcall
1087 (compile nil
1088 '(lambda (a)
1089 (if (logbitp 3
1090 (case -2
1091 ((-96879 -1035 -57680 -106404 -94516 -125088)
1092 (unwind-protect 90309179))
1093 ((-20811 -86901 -9368 -98520 -71594)
1094 (let ((v9 (unwind-protect 136707)))
1095 (block b3
1096 (setq v9
1097 (let ((v4 (return-from b3 v9)))
1098 (- (ignore-errors (return-from b3 v4))))))))
1099 (t -50)))
1100 -20343
1101 a)))
1103 -20343))
1105 ;;; MISC.165
1106 (assert (eql (funcall
1107 (compile
1109 '(lambda (a b c)
1110 (block b3
1111 (flet ((%f15
1112 (f15-1 f15-2 f15-3
1113 &optional
1114 (f15-4
1115 (flet ((%f17
1116 (f17-1 f17-2 f17-3
1117 &optional (f17-4 185155520) (f17-5 c)
1118 (f17-6 37))
1120 (%f17 -1046 a 1115306 (%f17 b -146330 422) -337817)))
1121 (f15-5 a) (f15-6 -40))
1122 (return-from b3 -16)))
1123 (multiple-value-call #'%f15 (values -519354 a 121 c -1905))))))
1124 0 0 -5)
1125 -16))
1127 ;;; MISC.172
1128 (assert (eql (funcall
1129 (compile
1131 '(lambda (a b c)
1132 (declare (notinline list apply))
1133 (declare (optimize (safety 3)))
1134 (declare (optimize (speed 0)))
1135 (declare (optimize (debug 0)))
1136 (labels ((%f12 (f12-1 f12-2)
1137 (labels ((%f2 (f2-1 f2-2)
1138 (flet ((%f6 ()
1139 (flet ((%f18
1140 (f18-1
1141 &optional (f18-2 a)
1142 (f18-3 -207465075)
1143 (f18-4 a))
1144 (return-from %f12 b)))
1145 (%f18 -3489553
1147 (%f18 (%f18 150 -64 f12-1)
1148 (%f18 (%f18 -8531)
1149 11410)
1151 56362666))))
1152 (labels ((%f7
1153 (f7-1 f7-2
1154 &optional (f7-3 (%f6)))
1155 7767415))
1156 f12-1))))
1157 (%f2 b -36582571))))
1158 (apply #'%f12 (list 774 -4413)))))
1159 0 1 2)
1160 774))
1162 ;;; MISC.173
1163 (assert (eql (funcall
1164 (compile
1166 '(lambda (a b c)
1167 (declare (notinline values))
1168 (declare (optimize (safety 3)))
1169 (declare (optimize (speed 0)))
1170 (declare (optimize (debug 0)))
1171 (flet ((%f11
1172 (f11-1 f11-2
1173 &optional (f11-3 c) (f11-4 7947114)
1174 (f11-5
1175 (flet ((%f3 (f3-1 &optional (f3-2 b) (f3-3 5529))
1176 8134))
1177 (multiple-value-call #'%f3
1178 (values (%f3 -30637724 b) c)))))
1179 (setq c 555910)))
1180 (if (and nil (%f11 a a))
1181 (if (%f11 a 421778 4030 1)
1182 (labels ((%f7
1183 (f7-1 f7-2
1184 &optional
1185 (f7-3
1186 (%f11 -79192293
1187 (%f11 c a c -4 214720)
1190 (%f11 b 985)))
1191 (f7-4 a))
1193 (%f11 c b -25644))
1195 -32326608))))
1196 1 2 3)
1197 -32326608))
1199 ;;; MISC.177, 182: IR2 copy propagation missed a hidden write to a
1200 ;;; local lambda argument
1201 (assert
1202 (equal
1203 (funcall
1204 (compile nil
1205 '(lambda (a b c)
1206 (declare (type (integer 804561 7640697) a))
1207 (declare (type (integer -1 10441401) b))
1208 (declare (type (integer -864634669 55189745) c))
1209 (declare (ignorable a b c))
1210 (declare (optimize (speed 3)))
1211 (declare (optimize (safety 1)))
1212 (declare (optimize (debug 1)))
1213 (flet ((%f11
1214 (f11-1 f11-2)
1215 (labels ((%f4 () (round 200048 (max 99 c))))
1216 (logand
1217 f11-1
1218 (labels ((%f3 (f3-1) -162967612))
1219 (%f3 (let* ((v8 (%f4)))
1220 (setq f11-1 (%f4)))))))))
1221 (%f11 -120429363 (%f11 62362 b)))))
1222 6714367 9645616 -637681868)
1223 -264223548))
1225 ;;; Bug reported by Paul F. Dietz caused by derive type loss in VALUE
1226 ;;; transform
1227 (assert (equal (multiple-value-list
1228 (funcall
1229 (compile nil '(lambda ()
1230 (declare (optimize (speed 1) (space 0) (safety 3) (debug 3) (compilation-speed 1)))
1231 (ceiling
1232 (ceiling
1233 (flet ((%f16 () 0)) (%f16))))))))
1234 '(0 0)))
1236 ;;; MISC.184
1237 (assert (zerop
1238 (funcall
1239 (compile
1241 '(lambda (a b c)
1242 (declare (type (integer 867934833 3293695878) a))
1243 (declare (type (integer -82111 1776797) b))
1244 (declare (type (integer -1432413516 54121964) c))
1245 (declare (optimize (speed 3)))
1246 (declare (optimize (safety 1)))
1247 (declare (optimize (debug 1)))
1248 (if nil
1249 (flet ((%f15 (f15-1 &optional (f15-2 c))
1250 (labels ((%f1 (f1-1 f1-2) 0))
1251 (%f1 a 0))))
1252 (flet ((%f4 ()
1253 (multiple-value-call #'%f15
1254 (values (%f15 c 0) (%f15 0)))))
1255 (if nil (%f4)
1256 (flet ((%f8 (f8-1 &optional (f8-2 (%f4)) (f8-3 0))
1257 f8-3))
1258 0))))
1259 0)))
1260 3040851270 1664281 -1340106197)))
1262 ;;; MISC.249
1263 (assert (zerop
1264 (funcall
1265 (compile
1267 '(lambda (a b)
1268 (declare (notinline <=))
1269 (declare (optimize (speed 2) (space 3) (safety 0)
1270 (debug 1) (compilation-speed 3)))
1271 (if (if (<= 0) nil nil)
1272 (labels ((%f9 (f9-1 f9-2 f9-3)
1273 (ignore-errors 0)))
1274 (dotimes (iv4 5 a) (%f9 0 0 b)))
1275 0)))
1276 1 2)))
1278 ;;; MISC.259-264 (aka "CSR screwed up implementing *-MOD32")
1279 (assert
1280 (= (funcall
1281 (compile
1283 '(lambda (a)
1284 (declare (type (integer 177547470 226026978) a))
1285 (declare (optimize (speed 3) (space 0) (safety 0) (debug 0)
1286 (compilation-speed 1)))
1287 (logand a (* a 438810))))
1288 215067723)
1289 13739018))
1292 ;;;; Bugs in stack analysis
1293 ;;; bug 299 (reported by PFD)
1294 (assert
1295 (equal (funcall
1296 (compile
1298 '(lambda ()
1299 (declare (optimize (debug 1)))
1300 (multiple-value-call #'list
1301 (if (eval t) (eval '(values :a :b :c)) nil)
1302 (catch 'foo (throw 'foo (values :x :y)))))))
1303 '(:a :b :c :x :y)))
1304 ;;; bug 298 (= MISC.183)
1305 (assert (zerop (funcall
1306 (compile
1308 '(lambda (a b c)
1309 (declare (type (integer -368154 377964) a))
1310 (declare (type (integer 5044 14959) b))
1311 (declare (type (integer -184859815 -8066427) c))
1312 (declare (ignorable a b c))
1313 (declare (optimize (speed 3)))
1314 (declare (optimize (safety 1)))
1315 (declare (optimize (debug 1)))
1316 (block b7
1317 (flet ((%f3 (f3-1 f3-2 f3-3) 0))
1318 (apply #'%f3 0 (catch 'foo (return-from b7 (%f3 0 b c))) c nil)))))
1319 0 6000 -9000000)))
1320 (assert (equal (eval '(let () (apply #'list 1 (list (catch 'a (throw 'a (block b 2)))))))
1321 '(1 2)))
1322 (let ((f (compile
1324 '(lambda (x)
1325 (block foo
1326 (multiple-value-call #'list
1328 (block bar
1329 (return-from foo
1330 (multiple-value-call #'list
1332 (block quux
1333 (return-from bar
1334 (catch 'baz
1335 (if x
1336 (return-from quux 1)
1337 (throw 'baz 2))))))))))))))
1338 (assert (equal (funcall f t) '(:b 1)))
1339 (assert (equal (funcall f nil) '(:a 2))))
1341 ;;; MISC.185
1342 (assert (equal
1343 (funcall
1344 (compile
1346 '(lambda (a b c)
1347 (declare (type (integer 5 155656586618) a))
1348 (declare (type (integer -15492 196529) b))
1349 (declare (type (integer 7 10) c))
1350 (declare (optimize (speed 3)))
1351 (declare (optimize (safety 1)))
1352 (declare (optimize (debug 1)))
1353 (flet ((%f3
1354 (f3-1 f3-2 f3-3
1355 &optional (f3-4 a) (f3-5 0)
1356 (f3-6
1357 (labels ((%f10 (f10-1 f10-2 f10-3)
1359 (apply #'%f10
1362 (- (if (equal a b) b (%f10 c a 0))
1363 (catch 'ct2 (throw 'ct2 c)))
1364 nil))))
1366 (%f3 (%f3 (%f3 b 0 0 0) a 0) a b b b c)))) 5 0 7)
1368 ;;; MISC.186
1369 (assert (eq
1370 (eval
1371 '(let* ((form '(labels ((%f3 (f3-1 f3-2) f3-1))
1372 (apply #'%f3 b (catch 'ct8 (throw 'ct8 (logeqv (%f3 c 0)))) nil)))
1373 (vars '(b c))
1374 (fn1 `(lambda ,vars
1375 (declare (type (integer -2 19) b)
1376 (type (integer -1520 218978) c)
1377 (optimize (speed 3) (safety 1) (debug 1)))
1378 ,form))
1379 (fn2 `(lambda ,vars
1380 (declare (notinline logeqv apply)
1381 (optimize (safety 3) (speed 0) (debug 0)))
1382 ,form))
1383 (cf1 (compile nil fn1))
1384 (cf2 (compile nil fn2))
1385 (result1 (multiple-value-list (funcall cf1 2 18886)))
1386 (result2 (multiple-value-list (funcall cf2 2 18886))))
1387 (if (equal result1 result2)
1388 :good
1389 (values result1 result2))))
1390 :good))
1392 ;;; MISC.290
1393 (assert (zerop
1394 (funcall
1395 (compile
1397 '(lambda ()
1398 (declare
1399 (optimize (speed 3) (space 3) (safety 1)
1400 (debug 2) (compilation-speed 0)))
1401 (apply (constantly 0) (catch 'ct2 0) 0 (catch 'ct2 0) nil))))))
1403 ;;; MISC.292
1404 (assert (zerop (funcall
1405 (compile
1407 '(lambda (a b)
1408 (declare (optimize (speed 2) (space 0) (safety 3) (debug 1)
1409 (compilation-speed 2)))
1410 (apply (constantly 0)
1413 (catch 'ct6
1414 (apply (constantly 0)
1417 (let* ((v1
1418 (let ((*s7* 0))
1419 b)))
1422 nil))
1424 nil)))
1425 1 2)))
1427 ;;; misc.295
1428 (assert (eql
1429 (funcall
1430 (compile
1432 '(lambda ()
1433 (declare (optimize (speed 1) (space 0) (safety 0) (debug 0)))
1434 (multiple-value-prog1
1435 (the integer (catch 'ct8 (catch 'ct7 15867134)))
1436 (catch 'ct1 (throw 'ct1 0))))))
1437 15867134))
1439 ;;; misc.361: replacing CAST with (m-v-call #'%compile-time-type-error)
1440 ;;; could transform known-values LVAR to UVL
1441 (assert (zerop (funcall
1442 (compile
1444 '(lambda (a b c)
1445 (declare (notinline boole values denominator list))
1446 (declare
1447 (optimize (speed 2)
1448 (space 0)
1449 (safety 1)
1450 (debug 0)
1451 (compilation-speed 2)))
1452 (catch 'ct6
1453 (progv
1454 '(*s8*)
1455 (list 0)
1456 (let ((v9 (ignore-errors (throw 'ct6 0))))
1457 (denominator
1458 (progv nil nil (values (boole boole-and 0 v9)))))))))
1459 1 2 3)))
1461 ;;; non-continuous dead UVL blocks
1462 (defun non-continuous-stack-test (x)
1463 (multiple-value-call #'list
1464 (eval '(values 11 12))
1465 (eval '(values 13 14))
1466 (block ext
1467 (return-from non-continuous-stack-test
1468 (multiple-value-call #'list
1469 (eval '(values :b1 :b2))
1470 (eval '(values :b3 :b4))
1471 (block int
1472 (return-from ext
1473 (multiple-value-call (eval #'values)
1474 (eval '(values 1 2))
1475 (eval '(values 3 4))
1476 (block ext
1477 (return-from int
1478 (multiple-value-call (eval #'values)
1479 (eval '(values :a1 :a2))
1480 (eval '(values :a3 :a4))
1481 (block int
1482 (return-from ext
1483 (multiple-value-call (eval #'values)
1484 (eval '(values 5 6))
1485 (eval '(values 7 8))
1486 (if x
1487 :ext
1488 (return-from int :int))))))))))))))))
1489 (assert (equal (non-continuous-stack-test t) '(11 12 13 14 1 2 3 4 5 6 7 8 :ext)))
1490 (assert (equal (non-continuous-stack-test nil) '(:b1 :b2 :b3 :b4 :a1 :a2 :a3 :a4 :int)))
1492 ;;; MISC.362: environment of UNWIND-PROTECTor is different from that
1493 ;;; if ENTRY.
1494 (assert (equal (multiple-value-list (funcall
1495 (compile
1497 '(lambda (b g h)
1498 (declare (optimize (speed 3) (space 3) (safety 2)
1499 (debug 2) (compilation-speed 3)))
1500 (catch 'ct5
1501 (unwind-protect
1502 (labels ((%f15 (f15-1 f15-2 f15-3)
1503 (rational (throw 'ct5 0))))
1504 (%f15 0
1505 (apply #'%f15
1508 (progn
1509 (progv '(*s2* *s5*) (list 0 (%f15 0 g 0)) b)
1511 nil)
1513 (common-lisp:handler-case 0)))))
1514 1 2 3))
1515 '(0)))
1518 ;;; MISC.275
1519 (assert
1520 (zerop
1521 (funcall
1522 (compile
1524 '(lambda (b)
1525 (declare (notinline funcall min coerce))
1526 (declare
1527 (optimize (speed 1)
1528 (space 2)
1529 (safety 2)
1530 (debug 1)
1531 (compilation-speed 1)))
1532 (flet ((%f12 (f12-1)
1533 (coerce
1534 (min
1535 (if f12-1 (multiple-value-prog1
1536 b (return-from %f12 0))
1538 'integer)))
1539 (funcall #'%f12 0))))
1540 -33)))
1542 ;;; Discussion of a CMUCL PCL bug on Sparc with Raymond Toy revealed a
1543 ;;; potential problem: optimizers and type derivers for MAX and MIN
1544 ;;; were not consistent in treating EQUALP, but not EQL, arguments.
1545 (dolist (f '(min max))
1546 (loop for complex-arg-args in '((1d0 2d0) (0d0 1d0))
1547 for complex-arg = `(if x ,@complex-arg-args)
1549 (loop for args in `((1 ,complex-arg)
1550 (,complex-arg 1))
1551 for form = `(,f ,@args)
1552 for f1 = (compile nil `(lambda (x) ,form))
1553 and f2 = (compile nil `(lambda (x) (declare (notinline min max))
1554 ,form))
1556 (dolist (x '(nil t))
1557 (assert (eql (funcall f1 x) (funcall f2 x)))))))
1560 (handler-case (compile nil '(lambda (x)
1561 (declare (optimize (speed 3) (safety 0)))
1562 (the double-float (sqrt (the double-float x)))))
1563 (sb-ext:compiler-note (c)
1564 ;; Ignore the note for the float -> pointer conversion of the
1565 ;; return value.
1566 (unless (string= (car (last (sb-c::simple-condition-format-arguments c)))
1567 "<return value>")
1568 (error "Compiler does not trust result type assertion."))))
1570 (let ((f (compile nil '(lambda (x)
1571 (declare (optimize speed (safety 0)))
1572 (block nil
1573 (the double-float
1574 (multiple-value-prog1
1575 (sqrt (the double-float x))
1576 (when (< x 0)
1577 (return :minus)))))))))
1578 (assert (eql (funcall f -1d0) :minus))
1579 (assert (eql (funcall f 4d0) 2d0)))
1581 ;;; bug 304: SBCL produced something similar to (/ (ASH x 4) 8)
1582 (handler-case
1583 (compile nil '(lambda (a i)
1584 (locally
1585 (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)
1586 (inhibit-warnings 0)))
1587 (declare (type (alien (* (unsigned 8))) a)
1588 (type (unsigned-byte 32) i))
1589 (deref a i))))
1590 (compiler-note (c)
1591 (unless (search "%ASH/RIGHT" (first (simple-condition-format-arguments c)))
1592 (error "The code is not optimized."))))
1594 (handler-case
1595 (compile nil '(lambda (x)
1596 (declare (type (integer -100 100) x))
1597 (declare (optimize speed))
1598 (declare (notinline identity))
1599 (1+ (identity x))))
1600 (compiler-note () (error "IDENTITY derive-type not applied.")))
1602 (assert (null (funcall (compile nil '(lambda (x) (funcall #'cddr x))) nil)))
1604 ;;; MISC.293 = easy variant of bug 303: repeated write to the same
1605 ;;; LVAR; here the first write may be cleared before the second is
1606 ;;; made.
1607 (assert
1608 (zerop
1609 (funcall
1610 (compile
1612 '(lambda ()
1613 (declare (notinline complex))
1614 (declare (optimize (speed 1) (space 0) (safety 1)
1615 (debug 3) (compilation-speed 3)))
1616 (flet ((%f () (multiple-value-prog1 0 (return-from %f 0))))
1617 (complex (%f) 0)))))))
1619 ;;; MISC.110A: CAST optimizer forgot to flush LVAR derived type
1620 (assert (zerop (funcall
1621 (compile
1623 '(lambda (a c)
1624 (declare (type (integer -1294746569 1640996137) a))
1625 (declare (type (integer -807801310 3) c))
1626 (declare (optimize (speed 3) (space 3) (safety 0) (debug 0) (compilation-speed 3)))
1627 (catch 'ct7
1629 (logbitp 0
1630 (if (/= 0 a)
1632 (ignore-errors
1633 (progn (if (ldb-test (byte 0 0) (rational (throw 'ct7 0))) 0 0) 0))))
1634 0 0))))
1635 391833530 -32785211)))
1637 ;;; efficiency notes for ordinary code
1638 (macrolet ((frob (arglist &body body)
1639 `(progn
1640 (handler-case
1641 (compile nil '(lambda ,arglist ,@body))
1642 (sb-ext:compiler-note (e)
1643 (error "bad compiler note for ~S:~% ~A" ',body e)))
1644 (let ((gotit nil))
1645 (handler-bind ((compiler-note
1646 (lambda (c)
1647 (setq gotit t) (muffle-warning c))))
1648 (compile nil '(lambda ,arglist (declare (optimize speed))
1649 ,@body)))
1650 (unless gotit
1651 (error "missing compiler note for ~S" ',body))))))
1652 (frob (x) (funcall x))
1653 (frob (x y) (find x y))
1654 (frob (x y) (find-if x y))
1655 (frob (x y) (find-if-not x y))
1656 (frob (x y) (position x y))
1657 (frob (x y) (position-if x y))
1658 (frob (x y) (position-if-not x y))
1659 (frob (x) (aref x 0)))
1661 (macrolet ((frob (style-warn-p form)
1662 (unless (eq (car form) 'lambda)
1663 (setq form `(lambda () ,form)))
1664 (if style-warn-p
1665 `(let ((gotit nil))
1666 (handler-bind ((style-warning
1667 (lambda (c)
1668 (setq gotit t) (muffle-warning c))))
1669 (compile nil ',form))
1670 (unless gotit
1671 (error "missing style-warning for ~S" ',form)))
1672 `(handler-case
1673 (compile nil ',form)
1674 (style-warning (e)
1675 (error "bad style-warning for ~S: ~A" ',form e))))))
1676 (frob t (lambda (x &optional y &key z) (list x y z)))
1677 (frob nil (lambda (x &optional y z) (list x y z)))
1678 (frob nil (lambda (x &key y z) (list x y z)))
1679 (frob t (defgeneric #:foo (x &optional y &key z)))
1680 (frob nil (defgeneric #:foo (x &optional y z)))
1681 (frob nil (defgeneric #:foo (x &key y z)))
1682 (frob t (defun #:foo (x) (flet ((foo (x &optional y &key z) (list x y z))) (foo x x :z x)))))
1684 ;;; this was a bug in the LOGXOR type deriver. The top form gave a
1685 ;;; note, because the system failed to derive the fact that the return
1686 ;;; from LOGXOR was small and negative, though the bottom one worked.
1687 (handler-bind ((sb-ext:compiler-note #'error))
1688 (compile nil '(lambda ()
1689 (declare (optimize speed (safety 0)))
1690 (lambda (x y)
1691 (declare (type (integer 3 6) x)
1692 (type (integer -6 -3) y))
1693 (+ (logxor x y) most-positive-fixnum)))))
1694 (handler-bind ((sb-ext:compiler-note #'error))
1695 (compile nil '(lambda ()
1696 (declare (optimize speed (safety 0)))
1697 (lambda (x y)
1698 (declare (type (integer 3 6) y)
1699 (type (integer -6 -3) x))
1700 (+ (logxor x y) most-positive-fixnum)))))
1702 ;;; check that modular ash gives the right answer, to protect against
1703 ;;; possible misunderstandings about the hardware shift instruction.
1704 (assert (zerop (funcall
1705 (compile nil '(lambda (x y)
1706 (declare (optimize speed)
1707 (type (unsigned-byte 32) x y))
1708 (logand #xffffffff (ash x y))))
1709 1 257)))
1711 ;;; code instrumenting problems
1712 (compile nil
1713 '(lambda ()
1714 (declare (optimize (debug 3)))
1715 (list (the integer (if nil 14 t)))))
1717 (compile nil
1718 '(LAMBDA (A B C D)
1719 (DECLARE (NOTINLINE LOGORC1 BYTE MASK-FIELD))
1720 (DECLARE
1721 (OPTIMIZE (SPEED 1)
1722 (SPACE 1)
1723 (SAFETY 1)
1724 (DEBUG 3)
1725 (COMPILATION-SPEED 0)))
1726 (MASK-FIELD (BYTE 7 26)
1727 (PROGN
1728 (TAGBODY (THE INTEGER (CATCH 'CT4 (LOGORC1 C -15950))) 1)
1729 B))))
1731 (compile nil
1732 '(lambda (buffer i end)
1733 (declare (optimize (debug 3)))
1734 (loop (when (not (eql 0 end)) (return)))
1735 (let ((s (make-string end)))
1736 (setf (schar s i) (schar buffer i))
1737 s)))
1739 ;;; check that constant string prefix and suffix don't cause the
1740 ;;; compiler to emit code deletion notes.
1741 (handler-bind ((sb-ext:code-deletion-note #'error))
1742 (compile nil '(lambda (s x)
1743 (pprint-logical-block (s x :prefix "(")
1744 (print x s))))
1745 (compile nil '(lambda (s x)
1746 (pprint-logical-block (s x :per-line-prefix ";")
1747 (print x s))))
1748 (compile nil '(lambda (s x)
1749 (pprint-logical-block (s x :suffix ">")
1750 (print x s)))))
1752 ;;; MISC.427: loop analysis requires complete DFO structure
1753 (assert (eql 17 (funcall
1754 (compile
1756 '(lambda (a)
1757 (declare (notinline list reduce logior))
1758 (declare (optimize (safety 2) (compilation-speed 1)
1759 (speed 3) (space 2) (debug 2)))
1760 (logior
1761 (let* ((v5 (reduce #'+ (list 0 a))))
1762 (declare (dynamic-extent v5))
1763 v5))))
1764 17)))
1766 ;;; MISC.434
1767 (assert (zerop (funcall
1768 (compile
1770 '(lambda (a b)
1771 (declare (type (integer -8431780939320 1571817471932) a))
1772 (declare (type (integer -4085 0) b))
1773 (declare (ignorable a b))
1774 (declare
1775 (optimize (space 2)
1776 (compilation-speed 0)
1777 #+sbcl (sb-c:insert-step-conditions 0)
1778 (debug 2)
1779 (safety 0)
1780 (speed 3)))
1781 (let ((*s5* 0))
1782 (dotimes (iv1 2 0)
1783 (let ((*s5*
1784 (elt '(1954479092053)
1785 (min 0
1786 (max 0
1787 (if (< iv1 iv1)
1788 (lognand iv1 (ash iv1 (min 53 iv1)))
1789 iv1))))))
1790 0)))))
1791 -7639589303599 -1368)))
1793 (compile
1795 '(lambda (a b)
1796 (declare (type (integer) a))
1797 (declare (type (integer) b))
1798 (declare (ignorable a b))
1799 (declare (optimize (space 2) (compilation-speed 0)
1800 (debug 0) (safety 0) (speed 3)))
1801 (dotimes (iv1 2 0)
1802 (when (< iv1 2) (print 'x)) ;; request for second constraint propagation pass
1803 (print (if (< iv1 iv1)
1804 (logand (ash iv1 iv1) 1)
1805 iv1)))))
1807 ;;; MISC.435: lambda var substitution in a deleted code.
1808 (assert (zerop (funcall
1809 (compile
1811 '(lambda (a b c d)
1812 (declare (notinline aref logandc2 gcd make-array))
1813 (declare
1814 (optimize (space 0) (safety 0) (compilation-speed 3)
1815 (speed 3) (debug 1)))
1816 (progn
1817 (tagbody
1818 (let* ((v2 (make-array nil :initial-element (catch 'ct1 (go tag2)))))
1819 (declare (dynamic-extent v2))
1820 (gcd (go tag2) (logandc2 (catch 'ct2 c) (aref v2))))
1821 tag2)
1822 0)))
1823 3021871717588 -866608 -2 -17194)))
1825 ;;; MISC.436, 438: lost reoptimization
1826 (assert (zerop (funcall
1827 (compile
1829 '(lambda (a b)
1830 (declare (type (integer -2917822 2783884) a))
1831 (declare (type (integer 0 160159) b))
1832 (declare (ignorable a b))
1833 (declare
1834 (optimize (compilation-speed 1)
1835 (speed 3)
1836 (safety 3)
1837 (space 0)
1838 ; #+sbcl (sb-c:insert-step-conditions 0)
1839 (debug 0)))
1841 (oddp
1842 (loop for
1844 below
1846 count
1847 (logbitp 0
1849 (ash b
1850 (min 8
1851 (count 0
1852 '(-10197561 486 430631291
1853 9674068))))))))
1855 0)))
1856 1265797 110757)))
1858 (assert (zerop (funcall
1859 (compile
1861 ' (lambda (a)
1862 (declare (type (integer 0 1696) a))
1863 ; (declare (ignorable a))
1864 (declare (optimize (space 2) (debug 0) (safety 1)
1865 (compilation-speed 0) (speed 1)))
1866 (if (logbitp 0 (ash (1- a) (min 11 a))) 0 0)))
1867 805)))
1869 ;;; bug #302
1870 (assert (compile
1872 '(lambda (s ei x y)
1873 (declare (type (simple-array function (2)) s) (type ei ei))
1874 (funcall (aref s ei) x y))))
1876 ;;; MISC.320: ir1-transform can create an intercomponent reference to
1877 ;;; a DEFINED-FUN.
1878 (assert (eql 102 (funcall
1879 (compile
1881 '(lambda ()
1882 (declare (optimize (speed 3) (space 0) (safety 2)
1883 (debug 2) (compilation-speed 0)))
1884 (catch 'ct2
1885 (elt '(102)
1886 (flet ((%f12 () (rem 0 -43)))
1887 (multiple-value-call #'%f12 (values))))))))))
1889 ;;; MISC.437: lost reoptimization after FLUSH-DEST
1890 (assert (zerop (funcall
1891 (compile
1893 '(lambda (a b c d e)
1894 (declare (notinline values complex eql))
1895 (declare
1896 (optimize (compilation-speed 3)
1897 (speed 3)
1898 (debug 1)
1899 (safety 1)
1900 (space 0)))
1901 (flet ((%f10
1902 (f10-1 f10-2 f10-3
1903 &optional (f10-4 (ignore-errors 0)) (f10-5 0)
1904 &key &allow-other-keys)
1905 (if (or (eql 0 0) t) 0 (if f10-1 0 0))))
1906 (complex (multiple-value-call #'%f10 (values a c b 0 0)) 0))))
1907 80043 74953652306 33658947 -63099937105 -27842393)))
1909 ;;; bug #351 -- program-error for malformed LET and LET*, including those
1910 ;;; resulting from SETF of LET.
1911 (with-test (:name :bug-351)
1912 (dolist (fun (list (compile nil '(lambda (x) (let :bogus-let :oops)))
1913 (compile nil '(lambda (x) (let* :bogus-let* :oops)))
1914 (compile nil '(lambda (x) (push x (let ((y 0)) y))))))
1915 (assert (functionp fun))
1916 (multiple-value-bind (res err) (ignore-errors (funcall fun t))
1917 (princ err) (terpri)
1918 (assert (not res))
1919 (assert (typep err 'program-error)))))
1921 (let ((fun (compile nil '(lambda (x) (random (if x 10 20))))))
1922 (dotimes (i 100 (error "bad RANDOM distribution"))
1923 (when (> (funcall fun nil) 9)
1924 (return t)))
1925 (dotimes (i 100)
1926 (when (> (funcall fun t) 9)
1927 (error "bad RANDOM event"))))
1929 ;;; 0.8.17.28-sma.1 lost derived type information.
1930 (with-test (:name :0.8.17.28-sma.1 :fails-on :sparc)
1931 (handler-bind ((sb-ext:compiler-note (lambda (c) (error "~A" c))))
1932 (compile nil
1933 '(lambda (x y v)
1934 (declare (optimize (speed 3) (safety 0)))
1935 (declare (type (integer 0 80) x)
1936 (type (integer 0 11) y)
1937 (type (simple-array (unsigned-byte 32) (*)) v))
1938 (setf (aref v 0) (* (* x #.(floor (ash 1 32) (* 11 80))) y))
1939 nil))))
1941 ;;; Bug reported by Robert J. Macomber: instrumenting of more-entry
1942 ;;; prevented open coding of %LISTIFY-REST-ARGS.
1943 (let ((f (compile nil '(lambda ()
1944 (declare (optimize (debug 3)))
1945 (with-simple-restart (blah "blah") (error "blah"))))))
1946 (handler-bind ((error (lambda (c) (invoke-restart 'blah))))
1947 (assert (equal (multiple-value-list (funcall f)) '(nil t)))))
1949 ;;; Bug reported by Timmy Douglas: overflow in bit vector setter with
1950 ;;; constant index and value.
1951 (loop for n-bits = 1 then (* n-bits 2)
1952 for type = `(unsigned-byte ,n-bits)
1953 and v-max = (1- (ash 1 n-bits))
1954 while (<= n-bits sb-vm:n-word-bits)
1956 (let* ((n (* 2 (1+ (- sb-vm::n-word-bits n-bits))))
1957 (array1 (make-array n :element-type type))
1958 (array2 (make-array n :element-type type)))
1959 (dotimes (i n)
1960 (dolist (v (list 0 v-max))
1961 (let ((f (compile nil `(lambda (a)
1962 (declare (type (simple-array ,type (,n)) a))
1963 (setf (aref a ,i) ,v)))))
1964 (fill array1 (- v-max v))
1965 (fill array2 (- v-max v))
1966 (funcall f array1)
1967 (setf (aref array2 i) v)
1968 (assert (every #'= array1 array2)))))))
1970 (let ((fn (compile nil '(lambda (x)
1971 (declare (type bit x))
1972 (declare (optimize speed))
1973 (let ((b (make-array 64 :element-type 'bit
1974 :initial-element 0)))
1975 (count x b))))))
1976 (assert (= (funcall fn 0) 64))
1977 (assert (= (funcall fn 1) 0)))
1979 (let ((fn (compile nil '(lambda (x y)
1980 (declare (type simple-bit-vector x y))
1981 (declare (optimize speed))
1982 (equal x y)))))
1983 (assert (funcall
1985 (make-array 64 :element-type 'bit :initial-element 0)
1986 (make-array 64 :element-type 'bit :initial-element 0)))
1987 (assert (not
1988 (funcall
1990 (make-array 64 :element-type 'bit :initial-element 0)
1991 (let ((b (make-array 64 :element-type 'bit :initial-element 0)))
1992 (setf (sbit b 63) 1)
1993 b)))))
1995 ;;; MISC.535: compiler failure
1996 (let ((c0 #c(4196.088977268509d0 -15943.3603515625d0)))
1997 (assert (not (funcall
1998 (compile
2000 `(lambda (p1 p2)
2001 (declare (optimize speed (safety 1))
2002 (type (eql ,c0) p1)
2003 (type number p2))
2004 (eql (the (complex double-float) p1) p2)))
2005 c0 #c(12 612/979)))))
2007 ;;; reported by Lutz Euler: we shouldn't signal a compiler note for
2008 ;;; simple-bit-vector functions.
2009 (with-test (:name (:simple-bit-vector :count :should-not-compiler-note))
2010 (handler-bind ((sb-ext:compiler-note (lambda (c) (error "~A" c))))
2011 (compile nil '(lambda (x)
2012 (declare (type simple-bit-vector x))
2013 (count 1 x)))))
2014 (with-test (:name (:simple-bit-vector :equal :should-not-compiler-note))
2015 (handler-bind ((sb-ext:compiler-note (lambda (c) (error "~A" c))))
2016 (compile nil '(lambda (x y)
2017 (declare (type simple-bit-vector x y))
2018 (equal x y)))))
2020 ;;; MISC.550: CAST merging in IR1 finalization caused unexpected
2021 ;;; code transformations.
2022 (assert (eql (funcall
2023 (compile
2025 '(lambda (p1 p2)
2026 (declare (optimize (speed 3) (safety 2) (debug 3) (space 3))
2027 (type atom p1)
2028 (type symbol p2))
2029 (or p1 (the (eql t) p2))))
2030 nil t)
2033 ;;; MISC.548: type check weakening converts required type into
2034 ;;; optional
2035 (assert (eql t
2036 (funcall
2037 (compile
2039 '(lambda (p1)
2040 (declare (optimize (speed 2) (safety 1) (debug 3) (space 2)))
2041 (atom (the (member f assoc-if write-line t w) p1))))
2042 t)))
2044 ;;; Free special bindings only apply to the body of the binding form, not
2045 ;;; the initialization forms.
2046 (assert (eq :good
2047 (funcall (compile 'nil
2048 '(lambda ()
2049 (let ((x :bad))
2050 (declare (special x))
2051 (let ((x :good))
2052 ((lambda (&optional (y x))
2053 (declare (special x)) y)))))))))
2055 ;;; Bug from pfdietz's random tester: the compiler knew that IMAGPART of
2056 ;;; a rational was zero, but didn't do the substitution, leading to a
2057 ;;; crash in the ASH vop (since a shift of 57 wouldn't fit in the
2058 ;;; machine's ASH instruction's immediate field) that the compiler
2059 ;;; thought was legitimate.
2060 (with-test (:name :overlarge-immediate-in-ash-vop)
2061 (checked-compile `(lambda (b)
2062 (declare (type (integer -2 14) b))
2063 (declare (ignorable b))
2064 (ash (imagpart b) 57))))
2066 ;;; bug reported by Eduardo Mu\~noz
2067 (with-test (:name (compile vector loop))
2068 (checked-compile
2069 `(lambda (struct first)
2070 (declare (optimize speed))
2071 (let* ((nodes (nodes struct))
2072 (bars (bars struct))
2073 (length (length nodes))
2074 (new (make-array length :fill-pointer 0)))
2075 (vector-push first new)
2076 (loop with i fixnum = 0
2077 for newl fixnum = (length new)
2078 while (< newl length) do
2079 (let ((oldl (length new)))
2080 (loop for j fixnum from i below newl do
2081 (dolist (n (node-neighbours (aref new j) bars))
2082 (unless (find n new)
2083 (vector-push n new))))
2084 (setq i oldl)))
2085 new))
2086 :allow-style-warnings t))
2088 ;;; bug #389: "0.0 can't be converted to type NIL." (Brian Rowe
2089 ;;; sbcl-devel)
2090 (with-test (:name (compile float :bug-389))
2091 (checked-compile `(lambda (x y a b c)
2092 (- y (* (signum x) (sqrt (abs (- (* b x) c))))))
2093 :allow-style-warnings t))
2095 ;;; Type inference from CHECK-TYPE
2096 (let ((count0 0) (count1 0))
2097 (handler-bind ((sb-ext:compiler-note (lambda (c) (incf count0))))
2098 (compile nil '(lambda (x)
2099 (declare (optimize (speed 3)))
2100 (1+ x))))
2101 ;; forced-to-do GENERIC-+, etc, possible word -> bignum conversion note
2102 (assert (> count0 1))
2103 (handler-bind ((sb-ext:compiler-note (lambda (c) (incf count1))))
2104 (compile nil '(lambda (x)
2105 (declare (optimize (speed 3)))
2106 (check-type x fixnum)
2107 (1+ x))))
2108 ;; Only the posssible word -> bignum conversion note
2109 (assert (= count1 1)))
2111 ;;; Up to 0.9.8.22 x86-64 had broken return value handling in the
2112 ;;; %SET-SAP-REF-DOUBLE/SINGLE VOPs.
2113 (with-test (:name :sap-ref-float)
2114 (compile nil '(lambda (sap)
2115 (let ((x (setf (sb-vm::sap-ref-double sap 0) 1d0)))
2116 (1+ x))))
2117 (compile nil '(lambda (sap)
2118 (let ((x (setf (sb-vm::sap-ref-single sap 0) 1d0)))
2119 (1+ x)))))
2121 ;;; bug #399
2122 (with-test (:name :string-union-types)
2123 (compile nil '(lambda (x)
2124 (declare (type (or (simple-array character (6))
2125 (simple-array character (5))) x))
2126 (aref x 0))))
2128 ;;; MISC.623: missing functions for constant-folding
2129 (assert (eql 0
2130 (funcall
2131 (compile
2133 '(lambda ()
2134 (declare (optimize (space 2) (speed 0) (debug 2)
2135 (compilation-speed 3) (safety 0)))
2136 (loop for lv3 below 1
2137 count (minusp
2138 (loop for lv2 below 2
2139 count (logbitp 0
2140 (bit #*1001101001001
2141 (min 12 (max 0 lv3))))))))))))
2143 ;;; MISC.624: erroneous AVER in x86's %LOGBITP VOPs
2144 (assert (eql 0
2145 (funcall
2146 (compile
2148 '(lambda (a)
2149 (declare (type (integer 21 28) a))
2150 (declare (optimize (compilation-speed 1) (safety 2)
2151 (speed 0) (debug 0) (space 1)))
2152 (let* ((v7 (flet ((%f3 (f3-1 f3-2)
2153 (loop for lv2 below 1
2154 count
2155 (logbitp 29
2156 (sbit #*10101111
2157 (min 7 (max 0 (eval '0))))))))
2158 (%f3 0 a))))
2159 0)))
2160 22)))
2162 ;;; MISC.626: bandaged AVER was still wrong
2163 (assert (eql -829253
2164 (funcall
2165 (compile
2167 '(lambda (a)
2168 (declare (type (integer -902970 2) a))
2169 (declare (optimize (space 2) (debug 0) (compilation-speed 1)
2170 (speed 0) (safety 3)))
2171 (prog2 (if (logbitp 30 a) 0 (block b3 0)) a)))
2172 -829253)))
2174 ;; MISC.628: constant-folding %LOGBITP was buggy
2175 (with-test (:name (compile logbitp :constant-folding))
2176 (assert (eql t
2177 (funcall
2178 (checked-compile
2179 `(lambda ()
2180 (declare (optimize (safety 3) (space 3) (compilation-speed 3)
2181 (speed 0) (debug 1)))
2182 (not (not (logbitp 0 (floor 2147483651 (min -23 0)))))))))))
2184 ;; mistyping found by random-tester
2185 (with-test (:name (compile :type-derivation))
2186 (assert (zerop
2187 (funcall
2188 (checked-compile
2189 `(lambda ()
2190 (declare (optimize (speed 1) (debug 0)
2191 (space 2) (safety 0) (compilation-speed 0)))
2192 (unwind-protect 0
2193 (* (/ (multiple-value-prog1 -29457482 -5602513511) 1)))))))))
2195 ;; aggressive constant folding (bug #400)
2196 (with-test (:name (compile :aggressive-constant-folding :bug-400))
2197 (assert
2198 (eq t (funcall (checked-compile `(lambda () (or t (the integer (/ 1 0)))))))))
2200 (with-test (:name (:compiler :constraint-propagation :var-eql-to-non-var-1))
2201 (checked-compile `(lambda (x y)
2202 (when (eql x (length y))
2203 (locally
2204 (declare (optimize (speed 3)))
2205 (1+ x))))
2206 :allow-notes '(not compiler-note)))
2208 (with-test (:name (:compiler :constraint-propagation :var-eql-to-non-var-2))
2209 (checked-compile `(lambda (x y)
2210 (when (eql (length y) x)
2211 (locally
2212 (declare (optimize (speed 3)))
2213 (1+ x))))
2214 :allow-notes '(not compiler-note)))
2216 (with-test (:name (:compiler :constraint-propagation :float-bounds-1))
2217 (checked-compile `(lambda (x)
2218 (declare (type (single-float * (3.0)) x))
2219 (when (<= x 2.0)
2220 (when (<= 2.0 x)
2221 x)))
2222 :allow-notes '(not compiler-note)))
2224 (defun assert-code-deletion-note (lambda &optional (howmany 1))
2225 (let ((notes (nth-value
2226 4 (checked-compile lambda :allow-notes 'code-deletion-note))))
2227 (assert (= howmany (length notes)))))
2229 (with-test (:name (:compiler :constraint-propagation :float-bounds-2))
2230 (assert-code-deletion-note
2231 `(lambda (x)
2232 (declare (type single-float x))
2233 (when (< 1.0 x)
2234 (when (<= x 1.0)
2235 (error "This is unreachable."))))))
2237 (with-test (:name (:compiler :constraint-propagation :float-bounds-3
2238 :LP-894498))
2239 (assert-code-deletion-note
2240 `(lambda (x)
2241 (declare (type (single-float 0.0) x))
2242 (when (> x 0.0)
2243 (when (zerop x)
2244 (error "This is unreachable."))))))
2246 (with-test (:name (:compiler :constraint-propagation :float-bounds-4
2247 :LP-894498))
2248 (assert-code-deletion-note
2249 `(lambda (x y)
2250 (declare (type (single-float 0.0) x)
2251 (type (single-float (0.0)) y))
2252 (when (> x y)
2253 (when (zerop x)
2254 (error "This is unreachable."))))))
2256 (with-test (:name (:compiler :constraint-propagation :var-eql-to-var-1))
2257 (assert-code-deletion-note
2258 `(lambda (x y)
2259 (when (typep y 'fixnum)
2260 (when (eql x y)
2261 (unless (typep x 'fixnum)
2262 (error "This is unreachable"))
2263 (setq y nil))))))
2265 (with-test (:name (:compiler :constraint-propagation :var-eql-to-var-2))
2266 (assert-code-deletion-note
2267 `(lambda (x y)
2268 (when (typep y 'fixnum)
2269 (when (eql y x)
2270 (unless (typep x 'fixnum)
2271 (error "This is unreachable"))
2272 (setq y nil))))))
2274 ;; Reported by John Wiseman, sbcl-devel
2275 ;; Subject: [Sbcl-devel] float type derivation bug?
2276 ;; Date: Tue, 4 Apr 2006 15:28:15 -0700
2277 (with-test (:name (compile :type-derivation :float-bounds))
2278 (checked-compile
2279 `(lambda (bits)
2280 (let* ((s (if (= (ash bits -31) 0) 1 -1))
2281 (e (logand (ash bits -23) #xff))
2282 (m (if (= e 0)
2283 (ash (logand bits #x7fffff) 1)
2284 (logior (logand bits #x7fffff) #x800000))))
2285 (float (* s m (expt 2 (- e 150))))))))
2287 ;; Reported by James Knight
2288 ;; Subject: [Sbcl-devel] AVER: "(EQ (SB-NAME (SC-SB (TN-SC TN))) 'REGISTERS)"
2289 ;; Date: Fri, 24 Mar 2006 19:30:00 -0500
2290 (with-test (:name (compile logbitp :vop))
2291 (checked-compile
2292 `(lambda (days shift)
2293 (declare (type fixnum shift days))
2294 (let* ((result 0)
2295 (canonicalized-shift (+ shift 1))
2296 (first-wrapping-day (- 1 canonicalized-shift)))
2297 (declare (type fixnum result))
2298 (dotimes (source-day 7)
2299 (declare (type (integer 0 6) source-day))
2300 (when (logbitp source-day days)
2301 (setf result
2302 (logior result
2303 (the fixnum
2304 (if (< source-day first-wrapping-day)
2305 (+ source-day canonicalized-shift)
2306 (- (+ source-day
2307 canonicalized-shift)
2308 7)))))))
2309 result))))
2311 ;;; MISC.637: incorrect delaying of conversion of optional entries
2312 ;;; with hairy constant defaults
2313 (with-test (:name (compile :optional-entry :hairy-defaults :misc.637))
2314 (let ((fun (checked-compile
2315 `(lambda ()
2316 (labels ((%f11 (f11-2 &key key1)
2317 (labels ((%f8 (f8-2 &optional (f8-5 (if nil (return-from %f11 0) 0)))
2318 :bad1))
2319 (%f8 (%f8 0)))
2320 :bad2))
2321 :good)))))
2322 (assert (eq (funcall fun) :good))))
2324 ;;; MISC.555: new reference to an already-optimized local function
2325 (with-test (:name (compile :already-optimized :local-function :misc.555))
2326 (let ((fun (checked-compile
2327 `(lambda (p1)
2328 (declare (optimize (speed 1) (safety 2) (debug 2) (space 0))
2329 (type keyword p1))
2330 (keywordp p1)))))
2331 (assert (funcall fun :good))
2332 (assert-error (funcall fun 42) type-error)))
2334 ;;; Check that the compiler doesn't munge *RANDOM-STATE*.
2335 (let* ((state (make-random-state))
2336 (*random-state* (make-random-state state))
2337 (a (random most-positive-fixnum)))
2338 (setf *random-state* state)
2339 (compile nil `(lambda (x a)
2340 (declare (single-float x)
2341 (type (simple-array double-float) a))
2342 (+ (loop for i across a
2343 summing i)
2344 x)))
2345 (assert (= a (random most-positive-fixnum))))
2347 ;;; MISC.641: LET-conversion after physical environment analysis lost NLX-INFOs
2348 (with-test (:name (compile let :conversion :lost :nlx-infos :misc.641))
2349 (let ((fun (checked-compile
2350 `(lambda ()
2351 (declare (optimize (speed 1) (space 0) (debug 2)
2352 (compilation-speed 0) (safety 1)))
2353 (flet ((%f3 (f3-1 &key (key1 (count (floor 0 (min -74 0)) #())))
2355 (apply #'%f3 0 nil)))
2356 :allow-style-warnings t)))
2357 (assert (zerop (funcall fun)))))
2359 ;;; size mismatch: #<SB-VM::EA :DWORD base=#<SB-C:TN t1[RDX]> disp=1> is a :DWORD and #<SB-C:TN t2[RAX]> is a :QWORD. on x86-64
2360 (with-test (:name (compile make-array aref :size-mismatch))
2361 (checked-compile `(lambda ()
2362 (let ((x (make-array '(1) :element-type '(signed-byte 32))))
2363 (setf (aref x 0) 1)))))
2365 ;;; step instrumentation confusing the compiler, reported by Faré
2366 (with-test (:name (compile step))
2367 (checked-compile `(lambda ()
2368 (declare (optimize (debug 2))) ; not debug 3!
2369 (let ((val "foobar"))
2370 (map-into (make-array (list (length val))
2371 :element-type '(unsigned-byte 8))
2372 #'char-code val)))))
2374 ;;; overconfident primitive type computation leading to bogus type
2375 ;;; checking.
2376 (with-test (:name (compile :primitive-type standard-object condition function))
2377 (flet ((test-case/incompatible (type1 type2 object1 object2)
2378 (multiple-value-bind (fun failure-p warnings)
2379 (checked-compile
2380 `(lambda (x)
2381 (declare (type (and ,type1 ,type2) x))
2383 :allow-failure t :allow-warnings t)
2384 (assert failure-p)
2385 (assert (= (length warnings) 1))
2386 ;; FIXME (declare (type <equivalent-to-empty-type> x)) is
2387 ;; currently dropped instead of compiled into a type
2388 ;; check.
2389 ;; (assert-error (funcall fun object1) type-error)
2390 ;; (assert-error (funcall fun object2) type-error)
2392 (test-case/compatible (type1 type2 object1 object2)
2393 (let ((fun (checked-compile
2394 `(lambda (x)
2395 (declare (type (and ,type1 ,type2) x))
2396 x))))
2397 (when (typep object1 type2)
2398 (assert (typep (funcall fun object1) type1)))
2399 (when (typep object2 type1)
2400 (assert (typep (funcall fun object2) type2))))))
2401 ;; TODO Add structure classes, SEQUENCE and EXTENDED-SEQUENCE
2402 (let ((types `((condition . ,(make-condition 'error))
2403 (sb-kernel:funcallable-instance . ,#'print-object)
2404 (function . ,#'identity)
2405 (sb-kernel:instance . ,(find-class 'class))
2406 (standard-object . ,(find-class 'class))))
2407 (compatible '((sb-kernel:instance . condition)
2408 (sb-kernel:instance . standard-object)
2409 (sb-kernel:funcallable-instance . function)
2410 (sb-kernel:funcallable-instance . standard-object)
2411 (function . standard-object))))
2412 (loop :for (type1 . object1) :in types :do
2413 (loop :for (type2 . object2) :in types :do
2414 (funcall
2415 (if (or (eq type1 type2)
2416 (find-if (lambda (cell)
2417 (or (and (eq type1 (car cell))
2418 (eq type2 (cdr cell)))
2419 (and (eq type2 (car cell))
2420 (eq type1 (cdr cell)))))
2421 compatible))
2422 #'test-case/compatible
2423 #'test-case/incompatible)
2424 type1 type2 object1 object2))))))
2426 ;;; LET* + VALUES declaration: while the declaration is a non-standard
2427 ;;; and possibly a non-conforming extension, as long as we do support
2428 ;;; it, we might as well get it right.
2430 ;;; Bug reported by Kaersten Poeck on sbcl-devel 20061023.
2431 (compile nil '(lambda () (let* () (declare (values list)))))
2434 ;;; test for some problems with too large immediates in x86-64 modular
2435 ;;; arithmetic vops
2436 (compile nil '(lambda (x) (declare (fixnum x))
2437 (logand most-positive-fixnum (logxor x most-positive-fixnum))))
2439 (compile nil '(lambda (x) (declare (fixnum x))
2440 (logand most-positive-fixnum (+ x most-positive-fixnum))))
2442 (compile nil '(lambda (x) (declare (fixnum x))
2443 (logand most-positive-fixnum (* x most-positive-fixnum))))
2445 ;;; bug 256.b
2446 (with-test (:name :propagate-type-through-error-and-binding)
2447 (assert (let (warned-p)
2448 (handler-bind ((warning (lambda (w) (setf warned-p t))))
2449 (compile nil
2450 '(lambda (x)
2451 (list (let ((y (the real x)))
2452 (unless (floatp y) (error ""))
2454 (integer-length x)))))
2455 warned-p)))
2457 ;; Dead / in safe code
2458 (with-test (:name :safe-dead-/)
2459 (assert (eq :error
2460 (handler-case
2461 (funcall (compile nil
2462 '(lambda (x y)
2463 (declare (optimize (safety 3)))
2464 (/ x y)
2465 (+ x y)))
2468 (division-by-zero ()
2469 :error)))))
2471 ;;; Dead unbound variable (bug 412)
2472 (with-test (:name :dead-unbound)
2473 (assert (eq :error
2474 (handler-case
2475 (funcall (compile nil
2476 '(lambda ()
2477 #:unbound
2478 42)))
2479 (unbound-variable ()
2480 :error)))))
2482 ;;; No compiler notes from compiling SUBSEQ SIMPLE-VECTOR.
2483 (handler-bind ((sb-ext:compiler-note 'error))
2484 (assert
2485 (equalp #(2 3)
2486 (funcall (compile nil `(lambda (s p e)
2487 (declare (optimize speed)
2488 (simple-vector s))
2489 (subseq s p e)))
2490 (vector 1 2 3 4)
2492 3))))
2494 ;;; No compiler notes from compiling COPY-SEQ SIMPLE-VECTOR.
2495 (handler-bind ((sb-ext:compiler-note 'error))
2496 (assert
2497 (equalp #(1 2 3 4)
2498 (funcall (compile nil `(lambda (s)
2499 (declare (optimize speed)
2500 (simple-vector s))
2501 (copy-seq s)))
2502 (vector 1 2 3 4)))))
2504 ;;; bug in adding DATA-VECTOR-REF-WITH-OFFSET to x86-64
2505 (assert (not (mismatch #(1.0f0 2.0f0) (make-array 2 :element-type 'single-float :initial-contents (list 1.0f0 2.0f0)))))
2507 ;;; bug in interval-arithmetic used by the compiler: needless attempt to coerce too
2508 ;;; large bignums to floats
2509 (dolist (op '(* / + -))
2510 (let ((fun (compile
2512 `(lambda (x)
2513 (declare (type (integer 0 #.(* 2 (truncate most-positive-double-float))) x))
2514 (,op 0.0d0 x)))))
2515 (loop repeat 10
2516 do (let ((arg (random (truncate most-positive-double-float))))
2517 (assert (eql (funcall fun arg)
2518 (funcall op 0.0d0 arg)))))))
2520 (with-test (:name :high-debug-known-function-inlining)
2521 (let ((fun (compile nil
2522 '(lambda ()
2523 (declare (optimize (debug 3)) (inline append))
2524 (let ((fun (lambda (body)
2525 (append
2526 (first body)
2527 nil))))
2528 (funcall fun
2529 '((foo (bar)))))))))
2530 (funcall fun)))
2532 (with-test (:name :high-debug-known-function-transform-with-optional-arguments)
2533 (compile nil '(lambda (x y)
2534 (declare (optimize sb-c::preserve-single-use-debug-variables))
2535 (if (block nil
2536 (some-unknown-function
2537 (lambda ()
2538 (return (member x y))))
2541 (error "~a" y)))))
2543 ;;; Compiling W-P-O when the pinned objects are known to be fixnums
2544 ;;; or characters.
2545 (compile nil '(lambda (x y)
2546 (declare (fixnum y) (character x))
2547 (sb-sys:with-pinned-objects (x y)
2548 (some-random-function))))
2550 ;;; *CHECK-CONSISTENCY* and TRULY-THE
2552 (with-test (:name :bug-423)
2553 (let ((sb-c::*check-consistency* t))
2554 (handler-bind ((warning #'error))
2555 (flet ((make-lambda (type)
2556 `(lambda (x)
2557 ((lambda (z)
2558 (if (listp z)
2559 (let ((q (truly-the list z)))
2560 (length q))
2561 (if (arrayp z)
2562 (let ((q (truly-the vector z)))
2563 (length q))
2564 (error "oops"))))
2565 (the ,type x)))))
2566 (compile nil (make-lambda 'list))
2567 (compile nil (make-lambda 'vector))))))
2569 ;;; this caused a momentary regression when an ill-adviced fix to
2570 ;;; bug 427 made ANY-REG suitable for primitive-type T:
2572 ;;; no :MOVE-ARG VOP defined to move #<SB-C:TN t1> (SC SB-VM::SINGLE-REG) to #<SB-C:TN t2> (SC SB-VM::ANY-REG)
2573 ;;; [Condition of type SIMPLE-ERROR]
2574 (compile nil
2575 '(lambda (frob)
2576 (labels
2577 ((%zig (frob)
2578 (typecase frob
2579 (double-float
2580 (setf (sb-alien:deref (sb-alien:cast (sb-alien:sap-alien (unknown1) (* unsigned-char))
2581 (* double-float))) frob))
2582 (hash-table
2583 (%zig (the (values (single-float (0.0) 1.0) &optional) (unknown2)))
2584 nil))))
2585 (%zig))))
2587 ;;; non-required arguments in HANDLER-BIND
2588 (assert (eq :oops (car (funcall (compile nil
2589 '(lambda (x)
2590 (block nil
2591 (handler-bind ((error (lambda (&rest args) (return (cons :oops args)))))
2592 (/ 2 x)))))
2593 0))))
2595 ;;; NIL is a legal function name
2596 (assert (eq 'a (flet ((nil () 'a)) (nil))))
2598 ;;; misc.528
2599 (assert (null (let* ((x 296.3066f0)
2600 (y 22717067)
2601 (form `(lambda (r p2)
2602 (declare (optimize speed (safety 1))
2603 (type (simple-array single-float nil) r)
2604 (type (integer -9369756340 22717335) p2))
2605 (setf (aref r) (* ,x (the (eql 22717067) p2)))
2606 (values)))
2607 (r (make-array nil :element-type 'single-float))
2608 (expected (* x y)))
2609 (funcall (compile nil form) r y)
2610 (let ((actual (aref r)))
2611 (unless (eql expected actual)
2612 (list expected actual))))))
2613 ;;; misc.529
2614 (assert (null (let* ((x -2367.3296f0)
2615 (y 46790178)
2616 (form `(lambda (r p2)
2617 (declare (optimize speed (safety 1))
2618 (type (simple-array single-float nil) r)
2619 (type (eql 46790178) p2))
2620 (setf (aref r) (+ ,x (the (integer 45893897) p2)))
2621 (values)))
2622 (r (make-array nil :element-type 'single-float))
2623 (expected (+ x y)))
2624 (funcall (compile nil form) r y)
2625 (let ((actual (aref r)))
2626 (unless (eql expected actual)
2627 (list expected actual))))))
2629 ;;; misc.556
2630 (assert (eql -1
2631 (funcall
2632 (compile nil '(lambda (p1 p2)
2633 (declare
2634 (optimize (speed 1) (safety 0)
2635 (debug 0) (space 0))
2636 (type (member 8174.8604) p1)
2637 (type (member -95195347) p2))
2638 (floor p1 p2)))
2639 8174.8604 -95195347)))
2641 ;;; misc.557
2642 (assert (eql -1
2643 (funcall
2644 (compile
2646 '(lambda (p1)
2647 (declare (optimize (speed 3) (safety 0) (debug 3) (space 1))
2648 (type (member -94430.086f0) p1))
2649 (floor (the single-float p1) 19311235)))
2650 -94430.086f0)))
2652 ;;; misc.558
2653 (assert (eql -1.0f0
2654 (funcall
2655 (compile
2657 '(lambda (p1)
2658 (declare (optimize (speed 1) (safety 2)
2659 (debug 2) (space 3))
2660 (type (eql -39466.56f0) p1))
2661 (ffloor p1 305598613)))
2662 -39466.56f0)))
2664 ;;; misc.559
2665 (assert (eql 1
2666 (funcall
2667 (compile
2669 '(lambda (p1)
2670 (declare (optimize (speed 1) (safety 1) (debug 1) (space 2))
2671 (type (eql -83232.09f0) p1))
2672 (ceiling p1 -83381228)))
2673 -83232.09f0)))
2675 ;;; misc.560
2676 (assert (eql 1
2677 (funcall
2678 (compile
2680 '(lambda (p1)
2681 (declare (optimize (speed 1) (safety 1)
2682 (debug 1) (space 0))
2683 (type (member -66414.414f0) p1))
2684 (ceiling p1 -63019173f0)))
2685 -66414.414f0)))
2687 ;;; misc.561
2688 (assert (eql 1.0f0
2689 (funcall
2690 (compile
2692 '(lambda (p1)
2693 (declare (optimize (speed 0) (safety 1)
2694 (debug 0) (space 1))
2695 (type (eql 20851.398f0) p1))
2696 (fceiling p1 80839863)))
2697 20851.398f0)))
2699 ;;; misc.581
2700 (assert (floatp
2701 (funcall
2702 (compile nil '(lambda (x)
2703 (declare (type (eql -5067.2056) x))
2704 (+ 213734822 x)))
2705 -5067.2056)))
2707 ;;; misc.581a
2708 (assert (typep
2709 (funcall
2710 (compile nil '(lambda (x) (declare (type (eql -1.0) x))
2711 (+ #x1000001 x)))
2712 -1.0f0)
2713 'single-float))
2715 ;;; misc.582
2716 (assert (plusp (funcall
2717 (compile
2719 ' (lambda (p1)
2720 (declare (optimize (speed 0) (safety 1) (debug 1) (space 1))
2721 (type (eql -39887.645) p1))
2722 (mod p1 382352925)))
2723 -39887.645)))
2725 ;;; misc.587
2726 (assert (let ((result (funcall
2727 (compile
2729 '(lambda (p2)
2730 (declare (optimize (speed 0) (safety 3) (debug 1) (space 0))
2731 (type (eql 33558541) p2))
2732 (- 92215.266 p2)))
2733 33558541)))
2734 (typep result 'single-float)))
2736 ;;; misc.635
2737 (assert (eql 1
2738 (let* ((form '(lambda (p2)
2739 (declare (optimize (speed 0) (safety 1)
2740 (debug 2) (space 2))
2741 (type (member -19261719) p2))
2742 (ceiling -46022.094 p2))))
2743 (values (funcall (compile nil form) -19261719)))))
2745 ;;; misc.636
2746 (assert (let* ((x 26899.875)
2747 (form `(lambda (p2)
2748 (declare (optimize (speed 3) (safety 1) (debug 3) (space 1))
2749 (type (member ,x #:g5437 char-code #:g5438) p2))
2750 (* 104102267 p2))))
2751 (floatp (funcall (compile nil form) x))))
2753 ;;; misc.622
2754 (assert (eql
2755 (funcall
2756 (compile
2758 '(lambda (p2)
2759 (declare (optimize (speed 3) (safety 2) (debug 3) (space 0))
2760 (type real p2))
2761 (+ 81535869 (the (member 17549.955 #:g35917) p2))))
2762 17549.955)
2763 (+ 81535869 17549.955)))
2765 ;;; misc.654
2766 (assert (eql 2
2767 (let ((form '(lambda (p2)
2768 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2769 (type (member integer eql) p2))
2770 (coerce 2 p2))))
2771 (funcall (compile nil form) 'integer))))
2773 ;;; misc.656
2774 (assert (eql 2
2775 (let ((form '(lambda (p2)
2776 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2777 (type (member integer mod) p2))
2778 (coerce 2 p2))))
2779 (funcall (compile nil form) 'integer))))
2781 ;;; misc.657
2782 (assert (eql 2
2783 (let ((form '(lambda (p2)
2784 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2785 (type (member integer values) p2))
2786 (coerce 2 p2))))
2787 (funcall (compile nil form) 'integer))))
2789 (with-test (:name :string-aref-type)
2790 (assert (eq 'character
2791 (funcall (compile nil
2792 '(lambda (s)
2793 (ctu:compiler-derived-type (aref (the string s) 0))))
2794 "foo"))))
2796 (with-test (:name :base-string-aref-type)
2797 (assert (eq #+sb-unicode 'base-char
2798 #-sb-unicode 'character
2799 (funcall (compile nil
2800 '(lambda (s)
2801 (ctu:compiler-derived-type (aref (the base-string s) 0))))
2802 (coerce "foo" 'base-string)))))
2804 (with-test (:name :dolist-constant-type-derivation)
2805 (assert (equal '(integer 1 3)
2806 (funcall (compile nil
2807 '(lambda (x)
2808 (dolist (y '(1 2 3))
2809 (when x
2810 (return (ctu:compiler-derived-type y))))))
2811 t))))
2813 (with-test (:name :dolist-simple-list-type-derivation)
2814 (assert (equal '(integer 1 3)
2815 (funcall (compile nil
2816 '(lambda (x)
2817 (dolist (y (list 1 2 3))
2818 (when x
2819 (return (ctu:compiler-derived-type y))))))
2820 t))))
2822 (with-test (:name :dolist-dotted-constant-list-type-derivation)
2823 (let* ((warned nil)
2824 (fun (handler-bind ((style-warning (lambda (c) (push c warned))))
2825 (compile nil
2826 '(lambda (x)
2827 (dolist (y '(1 2 3 . 4) :foo)
2828 (when x
2829 (return (ctu:compiler-derived-type y)))))))))
2830 (assert (equal '(integer 1 3) (funcall fun t)))
2831 (assert (= 1 (length warned)))
2832 (multiple-value-bind (res err) (ignore-errors (funcall fun nil))
2833 (assert (not res))
2834 (assert (typep err 'type-error)))))
2836 (with-test (:name :constant-list-destructuring)
2837 (handler-bind ((sb-ext:compiler-note #'error))
2838 (progn
2839 (assert (= 10
2840 (funcall
2841 (compile nil
2842 '(lambda ()
2843 (destructuring-bind (a (b c) d) '(1 (2 3) 4)
2844 (+ a b c d)))))))
2845 (assert (eq :feh
2846 (funcall
2847 (compile nil
2848 '(lambda (x)
2849 (or x
2850 (destructuring-bind (a (b c) d) '(1 "foo" 4)
2851 (+ a b c d)))))
2852 :feh))))))
2854 ;;; Functions with non-required arguments used to end up with
2855 ;;; (&OPTIONAL-DISPATCH ...) as their names.
2856 (with-test (:name :hairy-function-name)
2857 (assert (eq 'read-line (nth-value 2 (function-lambda-expression #'read-line))))
2858 (assert (equal "#<FUNCTION READ-LINE>" (princ-to-string #'read-line))))
2860 ;;; PROGV + RESTRICT-COMPILER-POLICY
2861 ;; META: there's a test in compiler.impure.lisp that also tests
2862 ;; interaction of PROGV with (debug 3). These tests should be together.
2863 (with-test (:name :progv-and-restrict-compiler-policy)
2864 (let ((sb-c::*policy-restrictions* sb-c::*policy-restrictions*))
2865 (restrict-compiler-policy 'debug 3)
2866 (let ((fun (compile nil '(lambda (x)
2867 (let ((i x))
2868 (declare (special i))
2869 (list i
2870 (progv '(i) (list (+ i 1))
2872 i))))))
2873 (assert (equal '(1 2 1) (funcall fun 1))))))
2875 ;;; It used to be possible to confuse the compiler into
2876 ;;; IR2-converting such a call to CONS
2877 (with-test (:name :late-bound-primitive)
2878 (compile nil `(lambda ()
2879 (funcall 'cons 1))))
2881 (with-test (:name :hairy-array-element-type-derivation)
2882 (compile nil '(lambda (x)
2883 (declare (type (and simple-string (satisfies array-has-fill-pointer-p)) x))
2884 (array-element-type x))))
2886 (with-test (:name :rest-list-type-derivation)
2887 (multiple-value-bind (type derivedp)
2888 (funcall (compile nil `(lambda (&rest args)
2889 (ctu:compiler-derived-type args)))
2890 nil)
2891 (assert (eq 'list type))
2892 (assert derivedp)))
2894 (with-test (:name :rest-list-type-derivation2)
2895 (multiple-value-bind (type derivedp)
2896 (funcall (funcall (compile nil `(lambda ()
2897 (lambda (&rest args)
2898 (ctu:compiler-derived-type args))))))
2899 (assert (eq 'list type))
2900 (assert derivedp)))
2902 (with-test (:name :rest-list-type-derivation3)
2903 (multiple-value-bind (type derivedp)
2904 (funcall (funcall (compile nil `(lambda ()
2905 (lambda (&optional x &rest args)
2906 (unless x (error "oops"))
2907 (ctu:compiler-derived-type args)))))
2909 (assert (eq 'list type))
2910 (assert derivedp)))
2912 (with-test (:name :rest-list-type-derivation4)
2913 (multiple-value-bind (type derivedp)
2914 (funcall (funcall (compile nil `(lambda ()
2915 (lambda (&optional x &rest args)
2916 (declare (type (or null integer) x))
2917 (when x (setf args x))
2918 (ctu:compiler-derived-type args)))))
2920 (assert (equal '(or cons null integer) type))
2921 (assert derivedp)))
2923 (with-test (:name :base-char-typep-elimination)
2924 (assert (eq (funcall (compile nil
2925 `(lambda (ch)
2926 (declare (type base-char ch) (optimize (speed 3) (safety 0)))
2927 (typep ch 'base-char)))
2929 t)))
2931 (with-test (:name :regression-1.0.24.37)
2932 (checked-compile `(lambda (&key (test (constantly t)))
2933 (when (funcall test)
2934 :quux))))
2936 ;;; Attempt to test a decent cross section of conditions
2937 ;;; and values types to move conditionally.
2938 (macrolet
2939 ((test-comparison (comparator type x y)
2940 `(progn
2941 ,@(loop for (result-type a b)
2942 in '((nil t nil)
2943 (nil 0 1)
2944 (nil 0.0 1.0)
2945 (nil 0d0 0d0)
2946 (nil 0.0 0d0)
2947 (nil #c(1.0 1.0) #c(2.0 2.0))
2949 (t t nil)
2950 (fixnum 0 1)
2951 ((unsigned-byte #.sb-vm:n-word-bits)
2952 (1+ most-positive-fixnum)
2953 (+ 2 most-positive-fixnum))
2954 ((signed-byte #.sb-vm:n-word-bits)
2955 -1 (* 2 most-negative-fixnum))
2956 (single-float 0.0 1.0)
2957 (double-float 0d0 1d0))
2958 for lambda = (if result-type
2959 `(lambda (x y a b)
2960 (declare (,type x y)
2961 (,result-type a b))
2962 (if (,comparator x y)
2963 a b))
2964 `(lambda (x y)
2965 (declare (,type x y))
2966 (if (,comparator x y)
2967 ,a ,b)))
2968 for args = `(,x ,y ,@(and result-type
2969 `(,a ,b)))
2970 collect
2971 `(progn
2972 (eql (funcall (checked-compile ',lambda)
2973 ,@args)
2974 (eval '(,lambda ,@args))))))))
2975 (sb-vm::with-float-traps-masked
2976 (:divide-by-zero :overflow :inexact :invalid)
2977 (let (#+sb-eval (sb-ext:*evaluator-mode* :interpret))
2978 (declare (sb-ext:muffle-conditions style-warning))
2979 (test-comparison eql t t nil)
2980 (test-comparison eql t t t)
2982 (test-comparison = t 1 0)
2983 (test-comparison = t 1 1)
2984 (test-comparison = t (1+ most-positive-fixnum) (+ 2 most-positive-fixnum))
2985 (test-comparison = fixnum 1 0)
2986 (test-comparison = fixnum 0 0)
2987 (test-comparison = (unsigned-byte #.sb-vm:n-word-bits) 1 0)
2988 (test-comparison = (unsigned-byte #.sb-vm:n-word-bits) 0 0)
2989 (test-comparison = (signed-byte #.sb-vm:n-word-bits) 1 0)
2990 (test-comparison = (signed-byte #.sb-vm:n-word-bits) 1 1)
2992 (test-comparison = single-float 0.0 1.0)
2993 (test-comparison = single-float 1.0 1.0)
2994 (test-comparison = single-float (/ 1.0 0.0) (/ 1.0 0.0))
2995 (test-comparison = single-float (/ 1.0 0.0) 1.0)
2996 (test-comparison = single-float (/ 0.0 0.0) (/ 0.0 0.0))
2997 (test-comparison = single-float (/ 0.0 0.0) 0.0)
2999 (test-comparison = double-float 0d0 1d0)
3000 (test-comparison = double-float 1d0 1d0)
3001 (test-comparison = double-float (/ 1d0 0d0) (/ 1d0 0d0))
3002 (test-comparison = double-float (/ 1d0 0d0) 1d0)
3003 (test-comparison = double-float (/ 0d0 0d0) (/ 0d0 0d0))
3004 (test-comparison = double-float (/ 0d0 0d0) 0d0)
3006 (test-comparison < t 1 0)
3007 (test-comparison < t 0 1)
3008 (test-comparison < t 1 1)
3009 (test-comparison < t (1+ most-positive-fixnum) (+ 2 most-positive-fixnum))
3010 (test-comparison < t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
3011 (test-comparison < fixnum 1 0)
3012 (test-comparison < fixnum 0 1)
3013 (test-comparison < fixnum 0 0)
3014 (test-comparison < (unsigned-byte #.sb-vm:n-word-bits) 1 0)
3015 (test-comparison < (unsigned-byte #.sb-vm:n-word-bits) 0 1)
3016 (test-comparison < (unsigned-byte #.sb-vm:n-word-bits) 0 0)
3017 (test-comparison < (signed-byte #.sb-vm:n-word-bits) 1 0)
3018 (test-comparison < (signed-byte #.sb-vm:n-word-bits) 0 1)
3019 (test-comparison < (signed-byte #.sb-vm:n-word-bits) 1 1)
3021 (test-comparison < single-float 0.0 1.0)
3022 (test-comparison < single-float 1.0 0.0)
3023 (test-comparison < single-float 1.0 1.0)
3024 (test-comparison < single-float (/ 1.0 0.0) (/ 1.0 0.0))
3025 (test-comparison < single-float (/ 1.0 0.0) 1.0)
3026 (test-comparison < single-float 1.0 (/ 1.0 0.0))
3027 (test-comparison < single-float (/ 0.0 0.0) (/ 0.0 0.0))
3028 (test-comparison < single-float (/ 0.0 0.0) 0.0)
3030 (test-comparison < double-float 0d0 1d0)
3031 (test-comparison < double-float 1d0 0d0)
3032 (test-comparison < double-float 1d0 1d0)
3033 (test-comparison < double-float (/ 1d0 0d0) (/ 1d0 0d0))
3034 (test-comparison < double-float (/ 1d0 0d0) 1d0)
3035 (test-comparison < double-float 1d0 (/ 1d0 0d0))
3036 (test-comparison < double-float (/ 0d0 0d0) (/ 0d0 0d0))
3037 (test-comparison < double-float (/ 0d0 0d0) 0d0)
3038 (test-comparison < double-float 0d0 (/ 0d0 0d0))
3040 (test-comparison > t 1 0)
3041 (test-comparison > t 0 1)
3042 (test-comparison > t 1 1)
3043 (test-comparison > t (1+ most-positive-fixnum) (+ 2 most-positive-fixnum))
3044 (test-comparison > t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
3045 (test-comparison > fixnum 1 0)
3046 (test-comparison > fixnum 0 1)
3047 (test-comparison > fixnum 0 0)
3048 (test-comparison > (unsigned-byte #.sb-vm:n-word-bits) 1 0)
3049 (test-comparison > (unsigned-byte #.sb-vm:n-word-bits) 0 1)
3050 (test-comparison > (unsigned-byte #.sb-vm:n-word-bits) 0 0)
3051 (test-comparison > (signed-byte #.sb-vm:n-word-bits) 1 0)
3052 (test-comparison > (signed-byte #.sb-vm:n-word-bits) 0 1)
3053 (test-comparison > (signed-byte #.sb-vm:n-word-bits) 1 1)
3055 (test-comparison > single-float 0.0 1.0)
3056 (test-comparison > single-float 1.0 0.0)
3057 (test-comparison > single-float 1.0 1.0)
3058 (test-comparison > single-float (/ 1.0 0.0) (/ 1.0 0.0))
3059 (test-comparison > single-float (/ 1.0 0.0) 1.0)
3060 (test-comparison > single-float 1.0 (/ 1.0 0.0))
3061 (test-comparison > single-float (/ 0.0 0.0) (/ 0.0 0.0))
3062 (test-comparison > single-float (/ 0.0 0.0) 0.0)
3064 (test-comparison > double-float 0d0 1d0)
3065 (test-comparison > double-float 1d0 0d0)
3066 (test-comparison > double-float 1d0 1d0)
3067 (test-comparison > double-float (/ 1d0 0d0) (/ 1d0 0d0))
3068 (test-comparison > double-float (/ 1d0 0d0) 1d0)
3069 (test-comparison > double-float 1d0 (/ 1d0 0d0))
3070 (test-comparison > double-float (/ 0d0 0d0) (/ 0d0 0d0))
3071 (test-comparison > double-float (/ 0d0 0d0) 0d0)
3072 (test-comparison > double-float 0d0 (/ 0d0 0d0)))))
3074 (with-test (:name :car-and-cdr-type-derivation-conservative)
3075 (let ((f1 (checked-compile
3076 `(lambda (y)
3077 (declare (optimize speed))
3078 (let ((x (the (cons fixnum fixnum) (cons 1 2))))
3079 (declare (type (cons t fixnum) x))
3080 (rplaca x y)
3081 (+ (car x) (cdr x))))))
3082 (f2 (checked-compile
3083 `(lambda (y)
3084 (declare (optimize speed))
3085 (let ((x (the (cons fixnum fixnum) (cons 1 2))))
3086 (setf (cdr x) y)
3087 (+ (car x) (cdr x)))))))
3088 (flet ((test-error (e value)
3089 (assert (typep e 'type-error))
3090 (assert (eq 'number (type-error-expected-type e)))
3091 (assert (eq value (type-error-datum e)))))
3092 (let ((v1 "foo")
3093 (v2 "bar"))
3094 (multiple-value-bind (res err) (ignore-errors (funcall f1 v1))
3095 (assert (not res))
3096 (test-error err v1))
3097 (multiple-value-bind (res err) (ignore-errors (funcall f2 v2))
3098 (assert (not res))
3099 (test-error err v2))))))
3101 (with-test (:name :array-dimension-derivation-conservative)
3102 (let ((f (checked-compile `(lambda (x)
3103 (declare (optimize speed))
3104 (declare (type (array * (4 4)) x))
3105 (let ((y x))
3106 (setq x (make-array '(4 4)))
3107 (adjust-array y '(3 5))
3108 (array-dimension y 0))))))
3109 (assert (= 3 (funcall f (make-array '(4 4) :adjustable t))))))
3111 (with-test (:name :with-timeout-code-deletion-note)
3112 (checked-compile `(lambda ()
3113 (sb-ext:with-timeout 0
3114 (sleep 1)))
3115 :allow-notes nil))
3117 (with-test (:name :full-warning-for-undefined-type-in-cl)
3118 (multiple-value-bind (fun failure-p warnings)
3119 (checked-compile `(lambda (x) (the replace x)) :allow-warnings t)
3120 (declare (ignore fun failure-p))
3121 (assert (= 1 (length warnings)))))
3123 (with-test (:name :single-warning-for-single-undefined-type)
3124 ;; STYLE-WARNING for symbol not in cl package.
3125 (multiple-value-bind (fun failure-p warnings style-warnings)
3126 (checked-compile `(lambda (x) (the #:no-type x))
3127 :allow-style-warnings t)
3128 (declare (ignore fun failure-p warnings))
3129 (assert (= 1 (length style-warnings))))
3131 ;; Full WARNING for invalid type specifier starting with QUOTE.
3132 (multiple-value-bind (fun failure-p warnings)
3133 (checked-compile `(lambda (x) (the 'fixnum x)) :allow-warnings t)
3134 (declare (ignore fun failure-p))
3135 (assert (= 1 (length warnings)))))
3137 (with-test (:name :complex-subtype-dumping-in-xc)
3138 (assert
3139 (= sb-vm:complex-single-float-widetag
3140 (sb-kernel:widetag-of
3141 (sb-vm:saetp-initial-element-default (sb-c::find-saetp '(complex single-float))))))
3142 (assert
3143 (= sb-vm:complex-double-float-widetag
3144 (sb-kernel:widetag-of
3145 (sb-vm:saetp-initial-element-default (sb-c::find-saetp '(complex double-float)))))))
3147 (with-test (:name :complex-single-float-fill)
3148 (assert (every (lambda (x) (= #c(1.0 2.0) x))
3149 (funcall
3150 (compile nil
3151 `(lambda (n x)
3152 (make-array (list n)
3153 :element-type '(complex single-float)
3154 :initial-element x)))
3156 #c(1.0 2.0)))))
3158 (with-test (:name :regression-1.0.28.21)
3159 (let ((fun (compile nil `(lambda (x) (typep x '(simple-array * 1))))))
3160 (assert (funcall fun (vector 1 2 3)))
3161 (assert (funcall fun "abc"))
3162 (assert (not (funcall fun (make-array '(2 2)))))))
3164 (with-test (:name :no-silly-compiler-notes-from-character-function)
3165 (dolist (name '(char-code char-int character char-name standard-char-p
3166 graphic-char-p alpha-char-p upper-case-p lower-case-p
3167 both-case-p digit-char-p alphanumericp digit-char-p))
3168 (checked-compile `(lambda (x)
3169 (declare (character x) (optimize (speed 3)))
3170 (,name x))
3171 :allow-notes nil))
3172 (dolist (name '(char= char/= char< char> char<= char>=
3173 char-lessp char-greaterp char-not-greaterp
3174 char-not-lessp))
3175 (checked-compile `(lambda (x y)
3176 (declare (character x y) (optimize speed))
3177 (,name x y))
3178 :allow-notes nil)))
3180 ;;; optimizing make-array
3181 (with-test (:name (make-array :open-code-initial-contents))
3182 (flet ((test (form)
3183 (assert (not (ctu:find-named-callees
3184 (checked-compile form))))))
3185 (test `(lambda (x y z)
3186 (make-array '(3) :initial-contents (list x y z))))
3187 (test `(lambda (x y z)
3188 (make-array '3 :initial-contents (vector x y z))))
3189 (test `(lambda (x y z)
3190 (make-array '3 :initial-contents `(,x ,y ,z))))
3191 (test `(lambda (x y z)
3192 ;; Single-use FLET is eliminated,
3193 ;; so MAKE-ARRAY's result is obviously a vector.
3194 (flet ((size () '(3)))
3195 (make-array (size) :initial-contents `(,x ,y ,z)))))
3196 (test `(lambda (x y z)
3197 (flet ((size () (list 3))) ; here too
3198 (make-array (size) :initial-contents `(,x ,y ,z)))))))
3200 ;;; optimizing array-in-bounds-p
3201 (with-test (:name :optimize-array-in-bounds-p)
3202 (locally
3203 (macrolet ((find-callees (&body body)
3204 `(ctu:find-named-callees
3205 (checked-compile '(lambda () ,@body))
3206 :name 'array-in-bounds-p))
3207 (must-optimize (&body exprs)
3208 `(progn
3209 ,@(loop for expr in exprs
3210 collect `(assert (not (find-callees
3211 ,expr))))))
3212 (must-not-optimize (&body exprs)
3213 `(progn
3214 ,@(loop for expr in exprs
3215 collect `(assert (find-callees
3216 ,expr))))))
3217 (must-optimize
3218 ;; in bounds
3219 (let ((a (make-array '(1))))
3220 (array-in-bounds-p a 0))
3221 ;; exceeds upper bound (constant)
3222 (let ((a (make-array '(1))))
3223 (array-in-bounds-p a 1))
3224 ;; exceeds upper bound (interval)
3225 (let ((a (make-array '(1))))
3226 (array-in-bounds-p a (+ 1 (random 2))))
3227 ;; negative lower bound (constant)
3228 (let ((a (make-array '(1))))
3229 (array-in-bounds-p a -1))
3230 ;; negative lower bound (interval)
3231 (let ((a (make-array 3))
3232 (i (- (random 1) 20)))
3233 (array-in-bounds-p a i))
3234 ;; multiple known dimensions
3235 (let ((a (make-array '(1 1))))
3236 (array-in-bounds-p a 0 0))
3237 ;; union types
3238 (let ((s (the (simple-string 10) (eval "0123456789"))))
3239 (array-in-bounds-p s 9)))
3240 (must-not-optimize
3241 ;; don't trust non-simple array length in safety=1
3242 (let ((a (the (array * (10 20)) (make-array '(10 20) :adjustable t))))
3243 (eval `(adjust-array ,a '(0 0)))
3244 (array-in-bounds-p a 9 0))
3245 ;; multiple unknown dimensions
3246 (let ((a (make-array (list (random 20) (random 5)))))
3247 (array-in-bounds-p a 5 2))
3248 ;; some other known dimensions
3249 (let ((a (make-array (list 1 (random 5)))))
3250 (array-in-bounds-p a 0 2))
3251 ;; subscript might be negative
3252 (let ((a (make-array '(5 10))))
3253 (array-in-bounds-p a 1 (- (random 3) 2)))
3254 ;; subscript might be too large
3255 (let ((a (make-array '(5 10))))
3256 (array-in-bounds-p a (random 6) 1))
3257 ;; unknown upper bound
3258 (let ((a (make-array '(5 10))))
3259 (array-in-bounds-p a (get-universal-time) 1))
3260 ;; unknown lower bound
3261 (let ((a (make-array '(5 30))))
3262 (array-in-bounds-p a 0 (- (get-universal-time))))
3263 ;; in theory we should be able to optimize
3264 ;; the following but the current implementation
3265 ;; doesn't cut it because the array type's
3266 ;; dimensions get reported as (* *).
3267 (let ((a (make-array (list (random 20) 1))))
3268 (array-in-bounds-p a 5 2))))))
3270 ;;; optimizing (EXPT -1 INTEGER)
3271 (with-test (:name (expt -1 integer))
3272 (dolist (x '(-1 -1.0 -1.0d0))
3273 (let ((fun (checked-compile `(lambda (x) (expt ,x (the fixnum x))))))
3274 (assert (not (ctu:find-named-callees fun)))
3275 (dotimes (i 12)
3276 (if (oddp i)
3277 (assert (eql x (funcall fun i)))
3278 (assert (eql (- x) (funcall fun i))))))))
3280 (with-test (:name :float-division-using-exact-reciprocal)
3281 (flet ((test (lambda-form arg res &key (check-insts t))
3282 (let* ((fun (checked-compile lambda-form))
3283 (disassembly (with-output-to-string (s)
3284 (disassemble fun :stream s))))
3285 ;; Let's make sure there is no division at runtime: for x86 and
3286 ;; x86-64 that implies an FDIV, DIVSS, or DIVSD instruction, so
3287 ;; look for DIV in the disassembly. It's a terrible KLUDGE, but
3288 ;; it works.
3289 #+(or x86 x86-64)
3290 (when check-insts
3291 (assert (not (search "DIV" disassembly))))
3292 ;; No generic arithmetic!
3293 (assert (not (search "GENERIC" disassembly)))
3294 (assert (eql res (funcall fun arg))))))
3295 (dolist (c '(128 64 32 16 8 4 2 1 1/2 1/4 1/8 1/16 1/32 1/64))
3296 (dolist (type '(single-float double-float))
3297 (let* ((cf (coerce c type))
3298 (arg (- (random (* 2 cf)) cf))
3299 (r1 (eval `(/ ,arg ,cf)))
3300 (r2 (eval `(/ ,arg ,(- cf)))))
3301 (test `(lambda (x) (declare (,type x)) (/ x ,cf)) arg r1)
3302 (test `(lambda (x) (declare (,type x)) (/ x ,(- cf))) arg r2)
3303 ;; rational args should get optimized as well
3304 (test `(lambda (x) (declare (,type x)) (/ x ,c)) arg r1)
3305 (test `(lambda (x) (declare (,type x)) (/ x ,(- c))) arg r2))))
3306 ;; Also check that inexact reciprocals (1) are not used by default (2) are
3307 ;; used with FLOAT-ACCURACY=0.
3308 (dolist (type '(single-float double-float))
3309 (let ((trey (coerce 3 type))
3310 (one (coerce 1 type)))
3311 (test `(lambda (x) (declare (,type x)) (/ x 3)) trey one
3312 :check-insts nil)
3313 (test `(lambda (x)
3314 (declare (,type x)
3315 (optimize (sb-c::float-accuracy 0)))
3316 (/ x 3))
3317 trey (eval `(* ,trey (/ ,trey))))))))
3319 (with-test (:name :float-multiplication-by-one)
3320 (flet ((test (lambda-form arg &optional (result arg))
3321 (let* ((fun1 (checked-compile lambda-form))
3322 (fun2 (funcall (checked-compile
3323 `(lambda ()
3324 (declare (optimize (sb-c::float-accuracy 0)))
3325 ,lambda-form))))
3326 (disassembly1 (with-output-to-string (s)
3327 (disassemble fun1 :stream s)))
3328 (disassembly2 (with-output-to-string (s)
3329 (disassemble fun2 :stream s))))
3330 ;; Multiplication at runtime should be eliminated only with
3331 ;; FLOAT-ACCURACY=0. (To catch SNaNs.)
3332 #+(or x86 x86-64)
3333 (assert (and (search "MUL" disassembly1)
3334 (not (search "MUL" disassembly2))))
3335 ;; Not generic arithmetic, please!
3336 (assert (and (not (search "GENERIC" disassembly1))
3337 (not (search "GENERIC" disassembly2))))
3338 (assert (eql result (funcall fun1 arg)))
3339 (assert (eql result (funcall fun2 arg))))))
3340 (dolist (type '(single-float double-float))
3341 (let* ((one (coerce 1 type))
3342 (arg (random (* 2 one)))
3343 (-r (- arg)))
3344 (test `(lambda (x) (declare (,type x)) (* x 1)) arg)
3345 (test `(lambda (x) (declare (,type x)) (* x -1)) arg -r)
3346 (test `(lambda (x) (declare (,type x)) (* x ,one)) arg)
3347 (test `(lambda (x) (declare (,type x)) (* x ,(- one))) arg -r)))))
3349 (with-test (:name :float-addition-of-zero)
3350 (flet ((test (lambda-form arg &optional (result arg))
3351 (let* ((fun1 (checked-compile lambda-form))
3352 (fun2 (funcall (checked-compile
3353 `(lambda ()
3354 (declare (optimize (sb-c::float-accuracy 0)))
3355 ,lambda-form))))
3356 (disassembly1 (with-output-to-string (s)
3357 (disassemble fun1 :stream s)))
3358 (disassembly2 (with-output-to-string (s)
3359 (disassemble fun2 :stream s))))
3360 ;; Let's make sure there is no addition at runtime: for x86 and
3361 ;; x86-64 that implies an FADD, ADDSS, or ADDSD instruction, so
3362 ;; look for the ADDs in the disassembly. It's a terrible KLUDGE,
3363 ;; but it works. Unless FLOAT-ACCURACY is zero, we leave the
3364 ;; addition in to catch SNaNs.
3365 #+x86
3366 (assert (and (search "FADD" disassembly1)
3367 (not (search "FADD" disassembly2))))
3368 #+x86-64
3369 (let ((inst (if (typep result 'double-float)
3370 "ADDSD" "ADDSS")))
3371 (assert (and (search inst disassembly1)
3372 (not (search inst disassembly2)))))
3373 (assert (eql result (funcall fun1 arg)))
3374 (assert (eql result (funcall fun2 arg))))))
3375 (test `(lambda (x) (declare (single-float x)) (+ x 0)) 123.45)
3376 (test `(lambda (x) (declare (single-float x)) (+ x 0.0)) 543.21)
3377 (test `(lambda (x) (declare (single-float x)) (+ x 0.0d0)) 42.00 42.d0)
3378 (test `(lambda (x) (declare (double-float x)) (+ x 0)) 123.45d0)
3379 (test `(lambda (x) (declare (double-float x)) (+ x 0.0)) 543.21d0)
3380 (test `(lambda (x) (declare (double-float x)) (+ x 0.0d0)) 42.d0)))
3382 (with-test (:name :float-substraction-of-zero)
3383 (flet ((test (lambda-form arg &optional (result arg))
3384 (let* ((fun1 (compile nil lambda-form))
3385 (fun2 (funcall (compile nil `(lambda ()
3386 (declare (optimize (sb-c::float-accuracy 0)))
3387 ,lambda-form))))
3388 (disassembly1 (with-output-to-string (s)
3389 (disassemble fun1 :stream s)))
3390 (disassembly2 (with-output-to-string (s)
3391 (disassemble fun2 :stream s))))
3392 ;; Let's make sure there is no substraction at runtime: for x86
3393 ;; and x86-64 that implies an FSUB, SUBSS, or SUBSD instruction,
3394 ;; so look for SUB in the disassembly. It's a terrible KLUDGE,
3395 ;; but it works. Unless FLOAT-ACCURACY is zero, we leave the
3396 ;; substraction in in to catch SNaNs.
3397 #+x86
3398 (assert (and (search "FSUB" disassembly1)
3399 (not (search "FSUB" disassembly2))))
3400 #+x86-64
3401 (let ((inst (if (typep result 'double-float)
3402 "SUBSD" "SUBSS")))
3403 (assert (and (search inst disassembly1)
3404 (not (search inst disassembly2)))))
3405 (assert (eql result (funcall fun1 arg)))
3406 (assert (eql result (funcall fun2 arg))))))
3407 (test `(lambda (x) (declare (single-float x)) (- x 0)) 123.45)
3408 (test `(lambda (x) (declare (single-float x)) (- x 0.0)) 543.21)
3409 (test `(lambda (x) (declare (single-float x)) (- x 0.0d0)) 42.00 42.d0)
3410 (test `(lambda (x) (declare (double-float x)) (- x 0)) 123.45d0)
3411 (test `(lambda (x) (declare (double-float x)) (- x 0.0)) 543.21d0)
3412 (test `(lambda (x) (declare (double-float x)) (- x 0.0d0)) 42.d0)))
3414 (with-test (:name :float-multiplication-by-two)
3415 (flet ((test (lambda-form arg &optional (result arg))
3416 (let* ((fun1 (compile nil lambda-form))
3417 (fun2 (funcall (compile nil `(lambda ()
3418 (declare (optimize (sb-c::float-accuracy 0)))
3419 ,lambda-form))))
3420 (disassembly1 (with-output-to-string (s)
3421 (disassemble fun1 :stream s)))
3422 (disassembly2 (with-output-to-string (s)
3423 (disassemble fun2 :stream s))))
3424 ;; Let's make sure there is no multiplication at runtime: for x86
3425 ;; and x86-64 that implies an FMUL, MULSS, or MULSD instruction,
3426 ;; so look for MUL in the disassembly. It's a terrible KLUDGE,
3427 ;; but it works.
3428 #+(or x86 x86-64)
3429 (assert (and (not (search "MUL" disassembly1))
3430 (not (search "MUL" disassembly2))))
3431 (assert (eql result (funcall fun1 arg)))
3432 (assert (eql result (funcall fun2 arg))))))
3433 (test `(lambda (x) (declare (single-float x)) (* x 2)) 123.45 246.9)
3434 (test `(lambda (x) (declare (single-float x)) (* x 2.0)) 543.21 1086.42)
3435 (test `(lambda (x) (declare (single-float x)) (* x 2.0d0)) 42.00 84.d0)
3436 (test `(lambda (x) (declare (double-float x)) (* x 2)) 123.45d0 246.9d0)
3437 (test `(lambda (x) (declare (double-float x)) (* x 2.0)) 543.21d0 1086.42d0)
3438 (test `(lambda (x) (declare (double-float x)) (* x 2.0d0)) 42.0d0 84.0d0)))
3440 (with-test (:name :bug-392203)
3441 ;; Used to hit an AVER in COMVERT-MV-CALL.
3442 (assert (zerop (funcall
3443 (checked-compile
3444 `(lambda ()
3445 (flet ((k (&rest x) (declare (ignore x)) 0))
3446 (multiple-value-call #'k #'k))))))))
3448 (with-test (:name :allocate-closures-failing-aver)
3449 (let ((f (checked-compile `(lambda ()
3450 (labels ((k (&optional x) #'k))))
3451 :allow-style-warnings t)))
3452 (assert (null (funcall f)))))
3454 (with-test (:name :flush-vector-creation :skipped-on :interpreter)
3455 (let ((f (checked-compile `(lambda ()
3456 (dotimes (i 1024)
3457 (vector i i i))
3458 t))))
3459 (ctu:assert-no-consing (funcall f))))
3461 (with-test (:name :array-type-predicates)
3462 (dolist (et (list* '(integer -1 200) '(integer -256 1)
3463 '(integer 0 128)
3464 '(integer 0 (128))
3465 '(double-float 0d0 (1d0))
3466 '(single-float (0s0) (1s0))
3467 '(or (eql 1d0) (eql 10d0))
3468 '(member 1 2 10)
3469 '(complex (member 10 20))
3470 '(complex (member 10d0 20d0))
3471 '(complex (member 10s0 20s0))
3472 '(or integer double-float)
3473 '(mod 1)
3474 '(member #\a #\b)
3475 '(eql #\a)
3476 #+sb-unicode 'extended-char
3477 #+sb-unicode '(eql #\cyrillic_small_letter_yu)
3478 sb-kernel::*specialized-array-element-types*))
3479 (when et
3480 (let* ((v (make-array 3 :element-type et))
3481 (fun (checked-compile
3482 `(lambda ()
3483 (list (if (typep ,v '(simple-array ,et (*)))
3484 :good
3485 :bad)
3486 (if (typep (elt ,v 0) '(simple-array ,et (*)))
3487 :bad
3488 :good))))))
3489 (assert (equal '(:good :good) (funcall fun)))))))
3491 (with-test (:name :truncate-float)
3492 (let ((s (checked-compile `(lambda (x)
3493 (declare (single-float x))
3494 (truncate x))))
3495 (d (checked-compile `(lambda (x)
3496 (declare (double-float x))
3497 (truncate x))))
3498 (s-inlined (checked-compile
3499 `(lambda (x)
3500 (declare (type (single-float 0.0s0 1.0s0) x))
3501 (truncate x))))
3502 (d-inlined (checked-compile
3503 `(lambda (x)
3504 (declare (type (double-float 0.0d0 1.0d0) x))
3505 (truncate x)))))
3506 ;; Check that there is no generic arithmetic
3507 (assert (not (search "GENERIC"
3508 (with-output-to-string (out)
3509 (disassemble s :stream out)))))
3510 (assert (not (search "GENERIC"
3511 (with-output-to-string (out)
3512 (disassemble d :stream out)))))
3513 ;; Check that we actually inlined the call when we were supposed to.
3514 (assert (not (search "UNARY-TRUNCATE"
3515 (with-output-to-string (out)
3516 (disassemble s-inlined :stream out)))))
3517 (assert (not (search "UNARY-TRUNCATE"
3518 (with-output-to-string (out)
3519 (disassemble d-inlined :stream out)))))))
3521 (with-test (:name (make-array :unnamed-dimension-leaf))
3522 (let ((fun (checked-compile `(lambda (stuff)
3523 (make-array (map 'list 'length stuff))))))
3524 (assert (equalp #2A((0 0 0) (0 0 0))
3525 (funcall fun '((1 2) (1 2 3)))))))
3527 (with-test (:name :fp-decoding-funs-not-flushable-in-safe-code)
3528 (dolist (name '(float-sign float-radix float-digits float-precision decode-float
3529 integer-decode-float))
3530 (let ((fun (checked-compile `(lambda (x)
3531 (declare (optimize safety))
3532 (,name x)
3533 nil))))
3534 (flet ((test (arg)
3535 (unless (eq :error
3536 (handler-case
3537 (funcall fun arg)
3538 (error () :error)))
3539 (error "(~S ~S) did not error"
3540 name arg))))
3541 ;; No error
3542 (funcall fun 1.0)
3543 ;; Error
3544 (test 'not-a-float)
3545 (when (member name '(decode-float integer-decode-float))
3546 (test sb-ext:single-float-positive-infinity))))))
3548 (with-test (:name :sap-ref-16)
3549 (let* ((fun (checked-compile
3550 `(lambda (x y)
3551 (declare (type sb-sys:system-area-pointer x)
3552 (type (integer 0 100) y))
3553 (sb-sys:sap-ref-16 x (+ 4 y)))))
3554 (vector (coerce '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
3555 '(simple-array (unsigned-byte 8) (*))))
3556 (sap (sb-sys:vector-sap vector))
3557 (ret (funcall fun sap 0)))
3558 ;; test for either endianness
3559 (assert (or (= ret (+ (* 5 256) 4)) (= ret (+ (* 4 256) 5))))))
3561 (with-test (:name (compile coerce :type-warning))
3562 (dolist (type '(t (unsigned-byte 8) (unsigned-byte 16) (unsigned-byte 32)
3563 (signed-byte 8) (signed-byte 16) (signed-byte 32)))
3564 (let ((fun (checked-compile `(lambda (x)
3565 (declare (type simple-vector x))
3566 (coerce x '(vector ,type))))))
3567 (assert (typep (funcall fun #(1)) `(simple-array ,type (*)))))))
3569 (with-test (:name (compile truncate double-float))
3570 (let ((fun (checked-compile `(lambda (x)
3571 (multiple-value-bind (q r)
3572 (truncate (coerce x 'double-float))
3573 (declare (type unsigned-byte q)
3574 (type double-float r))
3575 (list q r))))))
3576 (assert (equal (funcall fun 1.0d0) '(1 0.0d0)))))
3578 (with-test (:name :set-slot-value-no-warning)
3579 (let ((notes (nth-value
3580 4 (checked-compile `(lambda (x y)
3581 (declare (optimize speed safety))
3582 (setf (slot-value x 'bar) y))))))
3583 (assert (= 1 (length notes)))))
3585 (with-test (:name (concatenate :string-opt))
3586 (flet ((test (type grep)
3587 (let* ((fun (checked-compile `(lambda (a b c d e)
3588 (concatenate ',type a b c d e))))
3589 (args '("foo" #(#\.) "bar" (#\-) "quux"))
3590 (res (apply fun args)))
3591 (assert (search grep (with-output-to-string (out)
3592 (disassemble fun :stream out))))
3593 (assert (equal (apply #'concatenate type args)
3594 res))
3595 (assert (typep res type)))))
3596 #+sb-unicode
3597 (test 'string "%CONCATENATE-TO-STRING")
3598 #+sb-unicode
3599 (test 'simple-string "%CONCATENATE-TO-STRING")
3600 (test 'base-string "%CONCATENATE-TO-BASE-STRING")
3601 (test 'simple-base-string "%CONCATENATE-TO-BASE-STRING")))
3603 (with-test (:name (satisfies :no-local-fun))
3604 (let ((fun (checked-compile
3605 `(lambda (arg)
3606 (labels ((local-not-global-bug (x)
3608 (bar (x)
3609 (typep x '(satisfies local-not-global-bug))))
3610 (bar arg))))))
3611 (assert (eq 'local-not-global-bug
3612 (handler-case
3613 (funcall fun 42)
3614 (undefined-function (c)
3615 (cell-error-name c)))))))
3617 ;;; Prior to 1.0.32.x, dumping a fasl with a function with a default
3618 ;;; argument that is a complex structure (needing make-load-form
3619 ;;; processing) failed an AVER. The first attempt at a fix caused
3620 ;;; doing the same in-core to break.
3621 (with-test (:name :bug-310132)
3622 (checked-compile `(lambda (&optional (foo #p"foo/bar")))
3623 :allow-style-warnings t))
3625 (with-test (:name :bug-309129)
3626 (multiple-value-bind (fun failurep warnings)
3627 (checked-compile `(lambda (v) (values (svref v 0) (vector-pop v)))
3628 :allow-failure t :allow-warnings t)
3629 (assert failurep)
3630 (assert (= 1 (length warnings)))
3631 (handler-case (funcall fun #(1))
3632 (type-error (c)
3633 ;; we used to put simply VECTOR into EXPECTED-TYPE, rather
3634 ;; than explicitly (AND VECTOR (NOT SIMPLE-ARRAY))
3635 (assert (not (typep (type-error-datum c) (type-error-expected-type c)))))
3636 (:no-error (&rest values)
3637 (declare (ignore values))
3638 (error "no error")))))
3640 (with-test (:name (round :unary :type-derivation))
3641 (let ((fun (checked-compile
3642 `(lambda (zone)
3643 (multiple-value-bind (h m) (truncate (abs zone) 1.0)
3644 (declare (ignore h))
3645 (round (* 60.0 m)))))))
3646 (assert (= (funcall fun 0.5) 30))))
3648 (with-test (:name :bug-525949)
3649 (let ((fun (checked-compile
3650 `(lambda ()
3651 (labels ((always-one () 1)
3652 (f (z)
3653 (let ((n (funcall z)))
3654 (declare (fixnum n))
3655 (the double-float (expt n 1.0d0)))))
3656 (f #'always-one))))))
3657 (assert (= 1.0d0 (funcall fun)))))
3659 (with-test (:name :%array-data-vector-type-derivation)
3660 (let* ((f (checked-compile
3661 `(lambda (ary)
3662 (declare (type (simple-array (unsigned-byte 32) (3 3)) ary))
3663 (setf (aref ary 0 0) 0))))
3664 (text (with-output-to-string (s)
3665 (disassemble f :stream s))))
3666 (assert (not (search "OBJECT-NOT-SIMPLE-ARRAY-UNSIGNED-BYTE-32-ERROR" text)))))
3668 (with-test (:name :array-storage-vector-type-derivation)
3669 (let ((f (checked-compile
3670 `(lambda (ary)
3671 (declare (type (simple-array (unsigned-byte 32) (3 3)) ary))
3672 (ctu:compiler-derived-type (array-storage-vector ary))))))
3673 (assert (equal '(simple-array (unsigned-byte 32) (9))
3674 (funcall f (make-array '(3 3) :element-type '(unsigned-byte 32)))))))
3676 (with-test (:name :bug-523612)
3677 (let ((fun (checked-compile
3678 `(lambda (&key toff)
3679 (make-array 3 :element-type 'double-float
3680 :initial-contents
3681 (if toff (list toff 0d0 0d0) (list 0d0 0d0 0d0)))))))
3682 (assert (equalp (vector 0.0d0 0.0d0 0.0d0) (funcall fun :toff nil)))
3683 (assert (equalp (vector 2.3d0 0.0d0 0.0d0) (funcall fun :toff 2.3d0)))))
3685 (with-test (:name :bug-309788)
3686 (let ((fun (checked-compile `(lambda (x)
3687 (declare (optimize speed))
3688 (let ((env nil))
3689 (typep x 'fixnum env))))))
3690 (assert (not (ctu:find-named-callees fun)))))
3692 (with-test (:name :bug-309124)
3693 (let ((fun (checked-compile `(lambda (x)
3694 (declare (integer x))
3695 (declare (optimize speed))
3696 (cond ((typep x 'fixnum)
3697 "hala")
3698 ((typep x 'fixnum)
3699 "buba")
3700 ((typep x 'bignum)
3701 "hip")
3703 "zuz"))))))
3704 (assert (equal (list "hala" "hip")
3705 (sort (ctu:find-code-constants fun :type 'string)
3706 #'string<)))))
3708 (with-test (:name :bug-316078)
3709 (let ((fun (checked-compile
3710 `(lambda (x)
3711 (declare (type (and simple-bit-vector (satisfies bar)) x)
3712 (optimize speed))
3713 (elt x 5)))))
3714 (assert (not (ctu:find-named-callees fun)))
3715 (assert (= 1 (funcall fun #*000001)))
3716 (assert (= 0 (funcall fun #*000010)))))
3718 (with-test (:name :mult-by-one-in-float-acc-zero)
3719 (assert (eql 1.0 (funcall (checked-compile
3720 `(lambda (x)
3721 (declare (optimize (sb-c::float-accuracy 0)))
3722 (* x 1.0)))
3723 1)))
3724 (assert (eql -1.0 (funcall (checked-compile
3725 `(lambda (x)
3726 (declare (optimize (sb-c::float-accuracy 0)))
3727 (* x -1.0)))
3728 1)))
3729 (assert (eql 1.0d0 (funcall (checked-compile
3730 `(lambda (x)
3731 (declare (optimize (sb-c::float-accuracy 0)))
3732 (* x 1.0d0)))
3733 1)))
3734 (assert (eql -1.0d0 (funcall (checked-compile
3735 `(lambda (x)
3736 (declare (optimize (sb-c::float-accuracy 0)))
3737 (* x -1.0d0)))
3738 1))))
3740 (with-test (:name :dotimes-non-integer-counter-value)
3741 (assert-error (dotimes (i 8.6)) type-error))
3743 (with-test (:name :bug-454681)
3744 ;; This used to break due to reference to a dead lambda-var during
3745 ;; inline expansion.
3746 (assert (checked-compile
3747 `(lambda ()
3748 (multiple-value-bind (iterator+977 getter+978)
3749 (does-not-exist-but-does-not-matter)
3750 (flet ((iterator+976 ()
3751 (funcall iterator+977)))
3752 (declare (inline iterator+976))
3753 (let ((iterator+976 #'iterator+976))
3754 (funcall iterator+976)))))
3755 :allow-style-warnings t)))
3757 (with-test (:name :complex-float-local-fun-args)
3758 ;; As of 1.0.27.14, the lambda below failed to compile due to the
3759 ;; compiler attempting to pass unboxed complex floats to Z and the
3760 ;; MOVE-ARG method not expecting the register being used as a
3761 ;; temporary frame pointer. Reported by sykopomp in #lispgames,
3762 ;; reduced test case provided by _3b`.
3763 (checked-compile `(lambda (a)
3764 (labels ((z (b c)
3765 (declare ((complex double-float) b c))
3766 (* b (z b c))))
3767 (loop for i below 10 do
3768 (setf a (z a a)))))))
3770 (with-test (:name :bug-309130)
3771 (flet ((test (form)
3772 (let ((warnings (nth-value
3773 2 (checked-compile form :allow-warnings t))))
3774 (assert (= 1 (length warnings))))))
3775 (test `(lambda () (svref (make-array 8 :adjustable t) 1)))
3776 (test `(lambda (x)
3777 (declare (optimize (debug 0)))
3778 (declare (type vector x))
3779 (list (fill-pointer x) (svref x 1))))
3780 (test `(lambda (x)
3781 (list (vector-push (svref x 0) x))))
3782 (test `(lambda (x)
3783 (list (vector-push-extend (svref x 0) x))))))
3785 (with-test (:name :bug-646796)
3786 (assert (= 42 (funcall (checked-compile
3787 `(lambda ()
3788 (load-time-value (the (values fixnum) 42))))))))
3790 (with-test (:name :bug-654289)
3791 ;; Test that compile-times don't explode when quoted constants
3792 ;; get big.
3793 (labels ((time-n (n)
3794 (gc :full t) ; Let's not confuse the issue with GC
3795 (let* ((tree (make-tree (expt 10 n) nil))
3796 (t0 (get-internal-run-time))
3797 (f (compile nil `(lambda (x) (eq x (quote ,tree)))))
3798 (t1 (get-internal-run-time)))
3799 (assert (funcall f tree))
3800 (- t1 t0)))
3801 (make-tree (n acc)
3802 (cond ((zerop n) acc)
3803 (t (make-tree (1- n) (cons acc acc))))))
3804 (let* ((times (loop for i from 0 upto 4
3805 collect (time-n i)))
3806 (max-small (reduce #'max times :end 3))
3807 (max-big (reduce #'max times :start 3)))
3808 ;; This way is hopefully fairly CPU-performance insensitive.
3809 (unless (> (+ (truncate internal-time-units-per-second 10)
3810 (* 2 max-small))
3811 max-big)
3812 (error "Bad scaling or test? ~S" times)))))
3814 (with-test (:name :bug-309063)
3815 (let ((fun (compile nil `(lambda (x)
3816 (declare (type (integer 0 0) x))
3817 (ash x 100)))))
3818 (assert (zerop (funcall fun 0)))))
3820 (with-test (:name :bug-655872)
3821 (let ((f (compile nil `(lambda (x)
3822 (declare (optimize (safety 3)))
3823 (aref (locally (declare (optimize (safety 0)))
3824 (coerce x '(simple-vector 128)))
3825 60))))
3826 (long (make-array 100 :element-type 'fixnum)))
3827 (dotimes (i 100)
3828 (setf (aref long i) i))
3829 ;; 1. COERCE doesn't check the length in unsafe code.
3830 (assert (eql 60 (funcall f long)))
3831 ;; 2. The compiler doesn't trust the length from COERCE
3832 (assert (eq :caught
3833 (handler-case
3834 (funcall f (list 1 2 3))
3835 (sb-int:invalid-array-index-error (e)
3836 (assert (eql 60 (type-error-datum e)))
3837 (assert (equal '(integer 0 (3)) (type-error-expected-type e)))
3838 :caught))))))
3840 (with-test (:name :bug-655203-regression)
3841 (let ((fun (compile nil
3842 `(LAMBDA (VARIABLE)
3843 (LET ((CONTINUATION
3844 (LAMBDA
3845 (&OPTIONAL DUMMY &REST OTHER)
3846 (DECLARE (IGNORE OTHER))
3847 (PRIN1 DUMMY)
3848 (PRIN1 VARIABLE))))
3849 (FUNCALL CONTINUATION (LIST 1 2)))))))
3850 ;; This used to signal a bogus type-error.
3851 (assert (equal (with-output-to-string (*standard-output*)
3852 (funcall fun t))
3853 "(1 2)T"))))
3855 (with-test (:name :constant-concatenate-compile-time)
3856 (flet ((make-lambda (n)
3857 `(lambda (x)
3858 (declare (optimize (speed 3) (space 0)))
3859 (concatenate 'string x ,(make-string n)))))
3860 (let* ((l0 (make-lambda 1))
3861 (l1 (make-lambda 10))
3862 (l2 (make-lambda 100))
3863 (l3 (make-lambda 1000))
3864 (t0 (get-internal-run-time))
3865 (f0 (checked-compile l0))
3866 (t1 (get-internal-run-time))
3867 (f1 (checked-compile l1))
3868 (t2 (get-internal-run-time))
3869 (f2 (checked-compile l2))
3870 (t3 (get-internal-run-time))
3871 (f3 (checked-compile l3))
3872 (t4 (get-internal-run-time))
3873 (d0 (- t1 t0))
3874 (d1 (- t2 t1))
3875 (d2 (- t3 t2))
3876 (d3 (- t4 t3))
3877 (short-avg (/ (+ d0 d1 d2) 3)))
3878 (assert (and f0 f1 f2 f3))
3879 (assert (< d3 (* 10 short-avg))))))
3881 (with-test (:name :bug-384892)
3882 (assert (equal
3883 '(function (fixnum fixnum &key (:k1 boolean))
3884 (values (member t) &optional))
3885 (sb-kernel:%simple-fun-type
3886 (checked-compile `(lambda (x y &key k1)
3887 (declare (fixnum x y))
3888 (declare (boolean k1))
3889 (declare (ignore x y k1))
3890 t))))))
3892 (with-test (:name :bug-309448)
3893 ;; Like all tests trying to verify that something doesn't blow up
3894 ;; compile-times this is bound to be a bit brittle, but at least
3895 ;; here we try to establish a decent baseline.
3896 (labels ((time-it (lambda want &optional times)
3897 (gc :full t) ; let's keep GCs coming from other code out...
3898 (let* ((start (get-internal-run-time))
3899 (iterations 0)
3900 (fun (if times
3901 (loop repeat times
3902 for result = (checked-compile lambda)
3903 finally (return result))
3904 (loop for result = (checked-compile lambda)
3905 do (incf iterations)
3906 until (> (get-internal-run-time) (+ start 10))
3907 finally (return result))))
3908 (end (get-internal-run-time))
3909 (got (funcall fun)))
3910 (unless (eql want got)
3911 (error "wanted ~S, got ~S" want got))
3912 (values (- end start) iterations)))
3913 (test-it (simple result1 complex result2)
3914 (multiple-value-bind (time-simple iterations)
3915 (time-it simple result1)
3916 (assert (>= (* 10 (1+ time-simple))
3917 (time-it complex result2 iterations))))))
3918 ;; This is mostly identical as the next one, but doesn't create
3919 ;; hairy unions of numeric types.
3920 (test-it `(lambda ()
3921 (labels ((bar (baz bim)
3922 (let ((n (+ baz bim)))
3923 (* n (+ n 1) bim))))
3924 (let ((a (bar 1 1))
3925 (b (bar 1 1))
3926 (c (bar 1 1)))
3927 (- (+ a b) c))))
3929 `(lambda ()
3930 (labels ((bar (baz bim)
3931 (let ((n (+ baz bim)))
3932 (* n (+ n 1) bim))))
3933 (let ((a (bar 1 1))
3934 (b (bar 1 5))
3935 (c (bar 1 15)))
3936 (- (+ a b) c))))
3937 -3864)
3938 (test-it `(lambda ()
3939 (labels ((sum-d (n)
3940 (let ((m (truncate 999 n)))
3941 (/ (* n m (1+ m)) 2))))
3942 (- (+ (sum-d 3)
3943 (sum-d 3))
3944 (sum-d 3))))
3945 166833
3946 `(lambda ()
3947 (labels ((sum-d (n)
3948 (let ((m (truncate 999 n)))
3949 (/ (* n m (1+ m)) 2))))
3950 (- (+ (sum-d 3)
3951 (sum-d 5))
3952 (sum-d 15))))
3953 233168)))
3955 (with-test (:name :regression-1.0.44.34)
3956 (checked-compile
3957 `(lambda (z &rest args)
3958 (declare (dynamic-extent args))
3959 (flet ((foo (w v) (list v w)))
3960 (setq z 0)
3961 (flet ((foo ()
3962 (foo z args)))
3963 (declare (sb-int:truly-dynamic-extent #'foo))
3964 (call #'foo nil))))
3965 :allow-style-warnings t))
3967 (with-test (:name :bug-713626)
3968 (let ((f (eval '(constantly 42))))
3969 (assert (= 42 (funcall (checked-compile
3970 `(lambda () (funcall ,f 1 2 3))))))))
3972 (with-test (:name :known-fun-allows-other-keys)
3973 (funcall (checked-compile
3974 `(lambda () (directory "." :allow-other-keys t))))
3975 (funcall (checked-compile
3976 `(lambda () (directory "." :bar t :allow-other-keys t)))))
3978 (with-test (:name :bug-551227)
3979 ;; This function causes constraint analysis to perform a
3980 ;; ref-substitution that alters the A referred to in (G A) at in the
3981 ;; consequent of the IF to refer to be NUMBER, from the
3982 ;; LET-converted inline-expansion of MOD. This leads to attempting
3983 ;; to CLOSE-OVER a variable that simply isn't in scope when it is
3984 ;; referenced.
3985 (checked-compile
3986 `(lambda (a)
3987 (if (let ((s a))
3988 (block :block
3989 (map nil
3990 (lambda (e)
3991 (return-from :block
3992 (f (mod a e))))
3993 s)))
3994 (g a)))
3995 :allow-style-warnings t))
3997 (with-test (:name :funcall-lambda-inlined)
3998 (assert (not
3999 (ctu:find-code-constants
4000 (checked-compile `(lambda (x y)
4001 (+ x (funcall (lambda (z) z) y))))
4002 :type 'function))))
4004 (with-test (:name :bug-720382)
4005 (multiple-value-bind (fun failurep warnings)
4006 (checked-compile `(lambda (b) ((lambda () b) 1)) :allow-warnings t)
4007 (assert failurep)
4008 (assert (= 1 (length warnings)))
4009 (assert-error (funcall fun 0))))
4011 (with-test (:name :multiple-args-to-function)
4012 (let ((form `(flet ((foo (&optional (x 13)) x))
4013 (funcall (function foo 42))))
4014 #+sb-eval (*evaluator-mode* :interpret))
4015 #+sb-eval
4016 (assert (eq :error
4017 (handler-case (eval form)
4018 (error () :error))))
4019 (multiple-value-bind (fun warn fail)
4020 (compile nil `(lambda () ,form))
4021 (assert (and warn fail))
4022 (assert (eq :error
4023 (handler-case (funcall fun)
4024 (error () :error)))))))
4026 ;;; This doesn't test LVAR-FUN-IS directly, but captures it
4027 ;;; pretty accurately anyways.
4028 (with-test (:name :lvar-fun-is :skipped-on :interpreter)
4029 (dolist (fun (list
4030 (lambda (x) (member x x :test #'eq))
4031 (lambda (x) (member x x :test 'eq))
4032 (lambda (x) (member x x :test #.#'eq))))
4033 (assert (equal (list #'sb-kernel:%member-eq)
4034 (ctu:find-named-callees fun))))
4035 (dolist (fun (list
4036 (lambda (x)
4037 (declare (notinline eq))
4038 (member x x :test #'eq))
4039 (lambda (x)
4040 (declare (notinline eq))
4041 (member x x :test 'eq))
4042 (lambda (x)
4043 (declare (notinline eq))
4044 (member x x :test #.#'eq))))
4045 (assert (member #'sb-kernel:%member-test
4046 (ctu:find-named-callees fun)))))
4048 (with-test (:name :delete-to-delq-opt :skipped-on :interpreter)
4049 (dolist (fun (list (lambda (x y)
4050 (declare (list y))
4051 (delete x y :test #'eq))
4052 (lambda (x y)
4053 (declare (fixnum x) (list y))
4054 (delete x y))
4055 (lambda (x y)
4056 (declare (symbol x) (list y))
4057 (delete x y :test #'eql))))
4058 (assert (equal (list #'sb-int:delq)
4059 (ctu:find-named-callees fun)))))
4061 (with-test (:name :bug-767959)
4062 ;; This used to signal an error.
4063 (compile nil `(lambda ()
4064 (declare (optimize sb-c:store-coverage-data))
4065 (assoc
4067 '((:ordinary . ordinary-lambda-list))))))
4069 ;; This test failed formerly because the source transform of TYPEP would be
4070 ;; disabled when storing coverage data, thus giving no semantics to
4071 ;; expressions such as (TYPEP x 'INTEGER). The compiler could therefore not
4072 ;; prove that the else clause of the IF is unreachable - which it must be
4073 ;; since X is asserted to be fixnum. The conflicting requirement on X
4074 ;; that it be acceptable to LENGTH signaled a full warning.
4075 ;; Nobody on sbcl-devel could remember why the source transform was disabled,
4076 ;; but nobody disagreed with undoing the disabling.
4077 (with-test (:name :sb-cover-and-typep)
4078 (multiple-value-bind (fun warnings-p failure-p)
4079 (compile nil '(lambda (x)
4080 (declare (fixnum x) (optimize sb-c:store-coverage-data))
4081 (if (typep x 'integer) x (length x))))
4082 (assert (and fun (not warnings-p) (not failure-p)))))
4084 (with-test (:name :member-on-long-constant-list)
4085 ;; This used to blow stack with a sufficiently long list.
4086 (let ((cycle (list t)))
4087 (nconc cycle cycle)
4088 (compile nil `(lambda (x)
4089 (member x ',cycle)))))
4091 (with-test (:name :bug-722734)
4092 (assert-error
4093 (funcall (compile
4095 '(lambda ()
4096 (eql (make-array 6)
4097 (list unbound-variable-1 unbound-variable-2)))))))
4099 (with-test (:name :bug-771673)
4100 (assert (equal `(the foo bar) (macroexpand `(truly-the foo bar))))
4101 ;; Make sure the compiler doesn't use THE, and check that setf-expansions
4102 ;; work.
4103 (let ((f (compile nil `(lambda (x y)
4104 (setf (truly-the fixnum (car x)) y)))))
4105 (let* ((cell (cons t t)))
4106 (funcall f cell :ok)
4107 (assert (equal '(:ok . t) cell)))))
4109 (with-test (:name (:bug-793771 +))
4110 (let ((f (compile nil `(lambda (x y)
4111 (declare (type (single-float 2.0) x)
4112 (type (single-float (0.0)) y))
4113 (+ x y)))))
4114 (assert (equal `(function ((single-float 2.0) (single-float (0.0)))
4115 (values (single-float 2.0) &optional))
4116 (sb-kernel:%simple-fun-type f)))))
4118 (with-test (:name (:bug-793771 -))
4119 (let ((f (compile nil `(lambda (x y)
4120 (declare (type (single-float * 2.0) x)
4121 (type (single-float (0.0)) y))
4122 (- x y)))))
4123 (assert (equal `(function ((single-float * 2.0) (single-float (0.0)))
4124 (values (single-float * 2.0) &optional))
4125 (sb-kernel:%simple-fun-type f)))))
4127 (with-test (:name (:bug-793771 *))
4128 (let ((f (checked-compile
4129 `(lambda (x)
4130 (declare (type (single-float (0.0)) x))
4131 (* x 0.1)))))
4132 (assert (equal `(function ((single-float (0.0)))
4133 (values (single-float 0.0) &optional))
4134 (sb-kernel:%simple-fun-type f)))))
4136 (with-test (:name (:bug-793771 /))
4137 (let ((f (checked-compile
4138 `(lambda (x)
4139 (declare (type (single-float (0.0)) x))
4140 (/ x 3.0)))))
4141 (assert (equal `(function ((single-float (0.0)))
4142 (values (single-float 0.0) &optional))
4143 (sb-kernel:%simple-fun-type f)))))
4145 (with-test (:name (:bug-486812 single-float))
4146 (compile nil `(lambda ()
4147 (sb-kernel:make-single-float -1))))
4149 (with-test (:name (:bug-486812 double-float))
4150 (compile nil `(lambda ()
4151 (sb-kernel:make-double-float -1 0))))
4153 (with-test (:name :bug-729765)
4154 (compile nil `(lambda (a b)
4155 (declare ((integer 1 1) a)
4156 ((integer 0 1) b)
4157 (optimize debug))
4158 (lambda () (< b a)))))
4160 ;; Actually tests the assembly of RIP-relative operands to comparison
4161 ;; functions (one of the few x86 instructions that have extra bytes
4162 ;; *after* the mem operand's effective address, resulting in a wrong
4163 ;; offset).
4164 (with-test (:name :cmpps)
4165 (let ((foo (compile nil `(lambda (x)
4166 (= #C(2.0 3.0) (the (complex single-float) x))))))
4167 (assert (funcall foo #C(2.0 3.0)))
4168 (assert (not (funcall foo #C(1.0 2.0))))))
4170 (with-test (:name :cmppd)
4171 (let ((foo (compile nil `(lambda (x)
4172 (= #C(2d0 3d0) (the (complex double-float) x))))))
4173 (assert (funcall foo #C(2d0 3d0)))
4174 (assert (not (funcall foo #C(1d0 2d0))))))
4176 (with-test (:name :lvar-externally-checkable-type-nil)
4177 ;; Used to signal a BUG during compilation.
4178 (let ((fun (compile nil `(lambda (a) (parse-integer "12321321" (the (member :start) a) 1)))))
4179 (multiple-value-bind (i p) (funcall fun :start)
4180 (assert (= 2321321 i))
4181 (assert (= 8 p)))
4182 (multiple-value-bind (i e) (ignore-errors (funcall fun :end))
4183 (assert (not i))
4184 (assert (typep e 'type-error)))))
4186 (with-test (:name :simple-type-error-in-bound-propagation-a)
4187 (compile nil `(lambda (i)
4188 (declare (unsigned-byte i))
4189 (expt 10 (expt 7 (- 2 i))))))
4191 (with-test (:name :simple-type-error-in-bound-propagation-b)
4192 (assert (equal `(FUNCTION (UNSIGNED-BYTE)
4193 (VALUES (SINGLE-FLOAT -1F0 1F0) &OPTIONAL))
4194 (sb-kernel:%simple-fun-type
4195 (compile nil `(lambda (i)
4196 (declare (unsigned-byte i))
4197 (cos (expt 10 (+ 4096 i)))))))))
4199 (with-test (:name :fixed-%more-arg-values)
4200 (let ((fun (compile nil `(lambda (&rest rest)
4201 (declare (optimize (safety 0)))
4202 (apply #'cons rest)))))
4203 (assert (equal '(car . cdr) (funcall fun 'car 'cdr)))))
4205 (with-test (:name :bug-826970)
4206 (let ((fun (compile nil `(lambda (a b c)
4207 (declare (type (member -2 1) b))
4208 (array-in-bounds-p a 4 b c)))))
4209 (assert (funcall fun (make-array '(5 2 2)) 1 1))))
4211 (with-test (:name :bug-826971)
4212 (let* ((foo "foo")
4213 (fun (compile nil `(lambda (p1 p2)
4214 (schar (the (eql ,foo) p1) p2)))))
4215 (assert (eql #\f (funcall fun foo 0)))))
4217 (with-test (:name :bug-738464)
4218 (multiple-value-bind (fun warn fail)
4219 (compile nil `(lambda ()
4220 (flet ((foo () 42))
4221 (declare (ftype non-function-type foo))
4222 (foo))))
4223 (assert (eql 42 (funcall fun)))
4224 (assert (and warn (not fail)))))
4226 (with-test (:name :bug-832005)
4227 (let ((fun (compile nil `(lambda (x)
4228 (declare (type (complex single-float) x))
4229 (+ #C(0.0 1.0) x)))))
4230 (assert (= (funcall fun #C(1.0 2.0))
4231 #C(1.0 3.0)))))
4233 ;; A refactoring 1.0.12.18 caused lossy computation of primitive
4234 ;; types for member types.
4235 (with-test (:name :member-type-primitive-type)
4236 (let ((fun (compile nil `(lambda (p1 p2 p3)
4237 (if p1
4238 (the (member #c(1.2d0 1d0)) p2)
4239 (the (eql #c(1.0 1.0)) p3))))))
4240 (assert (eql (funcall fun 1 #c(1.2d0 1d0) #c(1.0 1.0))
4241 #c(1.2d0 1.0d0)))))
4243 ;; Fall-through jump elimination made control flow fall through to trampolines.
4244 ;; Reported by Eric Marsden on sbcl-devel@ 2011.10.26, with a test case
4245 ;; reproduced below (triggered a corruption warning and a memory fault).
4246 (with-test (:name :bug-883500)
4247 (funcall (compile nil `(lambda (a)
4248 (declare (type (integer -50 50) a))
4249 (declare (optimize (speed 0)))
4250 (mod (mod a (min -5 a)) 5)))
4253 ;; Test for literals too large for the ISA (e.g. (SIGNED-BYTE 13) on SPARC).
4254 #+sb-unicode
4255 (with-test (:name :bug-883519)
4256 (compile nil `(lambda (x)
4257 (declare (type character x))
4258 (eql x #\U0010FFFF))))
4260 ;; Wide fixnum platforms had buggy address computation in atomic-incf/aref
4261 (with-test (:name :bug-887220)
4262 (let ((incfer (compile
4264 `(lambda (vector index)
4265 (declare (type (simple-array sb-ext:word (4))
4266 vector)
4267 (type (mod 4) index))
4268 (sb-ext:atomic-incf (aref vector index) 1)
4269 vector))))
4270 (assert (equalp (funcall incfer
4271 (make-array 4 :element-type 'sb-ext:word
4272 :initial-element 0)
4274 #(0 1 0 0)))))
4276 (with-test (:name :catch-interferes-with-debug-names)
4277 (let ((fun (funcall
4278 (compile nil
4279 `(lambda ()
4280 (catch 'out
4281 (flet ((foo ()
4282 (throw 'out (lambda () t))))
4283 (foo))))))))
4284 (assert (equal '(lambda () :in foo) (sb-kernel:%fun-name fun)))))
4286 (with-test (:name :interval-div-signed-zero)
4287 (let ((fun (compile nil
4288 `(Lambda (a)
4289 (declare (type (member 0 -272413371076) a))
4290 (ffloor (the number a) -63243.127451934015d0)))))
4291 (multiple-value-bind (q r) (funcall fun 0)
4292 (assert (eql -0d0 q))
4293 (assert (eql 0d0 r)))))
4295 (with-test (:name :non-constant-keyword-typecheck)
4296 (let ((fun (compile nil
4297 `(lambda (p1 p3 p4)
4298 (declare (type keyword p3))
4299 (tree-equal p1 (cons 1 2) (the (member :test) p3) p4)))))
4300 (assert (funcall fun (cons 1.0 2.0) :test '=))))
4302 (with-test (:name :truncate-wild-values)
4303 (multiple-value-bind (q r)
4304 (handler-bind ((warning #'error))
4305 (let ((sb-c::*check-consistency* t))
4306 (funcall (compile nil
4307 `(lambda (a)
4308 (declare (type (member 1d0 2d0) a))
4309 (block return-value-tag
4310 (funcall
4311 (the function
4312 (catch 'debug-catch-tag
4313 (return-from return-value-tag
4314 (progn (truncate a)))))))))
4315 2d0)))
4316 (assert (eql 2 q))
4317 (assert (eql 0d0 r))))
4319 (with-test (:name :boxed-fp-constant-for-full-call)
4320 (let ((fun (compile nil
4321 `(lambda (x)
4322 (declare (double-float x))
4323 (unknown-fun 1.0d0 (+ 1.0d0 x))))))
4324 (assert (equal '(1.0d0) (ctu:find-code-constants fun :type 'double-float)))))
4326 (with-test (:name :only-one-boxed-constant-for-multiple-uses)
4327 (let* ((big (1+ most-positive-fixnum))
4328 (fun (compile nil
4329 `(lambda (x)
4330 (unknown-fun ,big (+ ,big x))))))
4331 (assert (= 1 (length (ctu:find-code-constants fun :type `(eql ,big)))))))
4333 (with-test (:name :fixnum+float-coerces-fixnum
4334 :skipped-on :x86)
4335 (let ((fun (compile nil
4336 `(lambda (x y)
4337 (declare (fixnum x)
4338 (single-float y))
4339 (+ x y)))))
4340 (assert (not (ctu:find-named-callees fun)))
4341 (assert (not (search "GENERIC"
4342 (with-output-to-string (s)
4343 (disassemble fun :stream s)))))))
4345 (with-test (:name :bug-803508)
4346 (compile nil `(lambda ()
4347 (print
4348 (lambda (bar)
4349 (declare (dynamic-extent bar))
4350 (foo bar))))))
4352 (with-test (:name :bug-803508-b)
4353 (compile nil `(lambda ()
4354 (list
4355 (lambda (bar)
4356 (declare (dynamic-extent bar))
4357 (foo bar))))))
4359 (with-test (:name :bug-803508-c)
4360 (compile nil `(lambda ()
4361 (list
4362 (lambda (bar &optional quux)
4363 (declare (dynamic-extent bar quux))
4364 (foo bar quux))))))
4366 (with-test (:name :cprop-with-constant-but-assigned-to-closure-variable)
4367 (compile nil `(lambda (b c d)
4368 (declare (type (integer -20545789 207590862) c))
4369 (declare (type (integer -1 -1) d))
4370 (let ((i (unwind-protect 32 (shiftf d -1))))
4371 (or (if (= d c) 2 (= 3 b)) 4)))))
4373 (with-test (:name :bug-913232
4374 :fails-on :interpreter) ; no idea why it fails randomly
4375 (compile nil `(lambda (x)
4376 (declare (optimize speed)
4377 (type (or (and (or (integer -100 -50)
4378 (integer 100 200)) (satisfies foo))
4379 (and (or (integer 0 10) (integer 20 30)) a)) x))
4381 (compile nil `(lambda (x)
4382 (declare (optimize speed)
4383 (type (and fixnum a) x))
4384 x)))
4386 (with-test (:name :bug-959687)
4387 (multiple-value-bind (fun warn fail)
4388 (compile nil `(lambda (x)
4389 (case x
4391 :its-a-t)
4392 (otherwise
4393 :somethign-else))))
4394 (assert (and warn fail))
4395 (assert (not (ignore-errors (funcall fun t)))))
4396 (multiple-value-bind (fun warn fail)
4397 (compile nil `(lambda (x)
4398 (case x
4399 (otherwise
4400 :its-an-otherwise)
4402 :somethign-else))))
4403 (assert (and warn fail))
4404 (assert (not (ignore-errors (funcall fun t))))))
4406 (with-test (:name :bug-924276)
4407 (assert (eq :style-warning
4408 (handler-case
4409 (compile nil `(lambda (a)
4410 (cons a (symbol-macrolet ((b 1))
4411 (declare (ignorable a))
4412 :c))))
4413 (style-warning ()
4414 :style-warning)))))
4416 (with-test (:name :bug-974406)
4417 (let ((fun32 (compile nil `(lambda (x)
4418 (declare (optimize speed (safety 0)))
4419 (declare (type (integer 53 86) x))
4420 (logand (+ x 1032791128) 11007078467))))
4421 (fun64 (compile nil `(lambda (x)
4422 (declare (optimize speed (safety 0)))
4423 (declare (type (integer 53 86) x))
4424 (logand (+ x 1152921504606846975)
4425 38046409652025950207)))))
4426 (assert (= (funcall fun32 61) 268574721))
4427 (assert (= (funcall fun64 61) 60)))
4428 (let (result)
4429 (do ((width 5 (1+ width)))
4430 ((= width 130))
4431 (dotimes (extra 4)
4432 (let ((fun (compile nil `(lambda (x)
4433 (declare (optimize speed (safety 0)))
4434 (declare (type (integer 1 16) x))
4435 (logand
4436 (+ x ,(1- (ash 1 width)))
4437 ,(logior (ash 1 (+ width 1 extra))
4438 (1- (ash 1 width))))))))
4439 (unless (= (funcall fun 16) (logand 15 (1- (ash 1 width))))
4440 (push (cons width extra) result)))))
4441 (assert (null result))))
4443 ;; On x86-64 MOVE-IMMEDIATE of fixnum values into memory either directly
4444 ;; uses a MOV into memory or goes through a temporary register if the
4445 ;; value is larger than a certain number of bits. Check that it respects
4446 ;; the limits of immediate arguments to the MOV instruction (if not, the
4447 ;; assembler will fail an assertion) and doesn't have sign-extension
4448 ;; problems. (The test passes fixnum constants through the MOVE VOP
4449 ;; which calls MOVE-IMMEDIATE.)
4450 (with-test (:name :constant-fixnum-move)
4451 (let ((f (compile nil `(lambda (g)
4452 (funcall g
4453 ;; The first three args are
4454 ;; uninteresting as they are
4455 ;; passed in registers.
4456 1 2 3
4457 ,@(loop for i from 27 to 32
4458 collect (expt 2 i)))))))
4459 (assert (every #'plusp (funcall f #'list)))))
4461 (with-test (:name (:malformed-ignore :lp-1000239) :skipped-on :interpreter)
4462 (assert-error
4463 (eval '(lambda () (declare (ignore (function . a)))))
4464 sb-int:simple-program-error)
4465 (assert-error
4466 (eval '(lambda () (declare (ignore (function a b)))))
4467 sb-int:simple-program-error)
4468 (assert-error
4469 (eval '(lambda () (declare (ignore (function)))))
4470 sb-int:simple-program-error)
4471 (assert-error
4472 (eval '(lambda () (declare (ignore (a)))))
4473 sb-int:simple-program-error)
4474 (assert-error
4475 (eval '(lambda () (declare (ignorable (a b)))))
4476 sb-int:simple-program-error))
4478 (with-test (:name :malformed-type-declaraions)
4479 (compile nil '(lambda (a) (declare (type (integer 1 2 . 3) a)))))
4481 (with-test (:name :compiled-program-error-escaped-source)
4482 (assert
4483 (handler-case
4484 (funcall (compile nil `(lambda () (lambda ("foo")))))
4485 (sb-int:compiled-program-error (e)
4486 (let ((source (read-from-string (sb-kernel::program-error-source e))))
4487 (equal source '#'(lambda ("foo"))))))))
4489 (with-test (:name :escape-analysis-for-nlxs :skipped-on :interpreter)
4490 (flet ((test (check lambda &rest args)
4491 (let* ((cell-note nil)
4492 (fun (handler-bind ((compiler-note
4493 (lambda (note)
4494 (when (search
4495 "Allocating a value-cell at runtime for"
4496 (princ-to-string note))
4497 (setf cell-note t)))))
4498 (compile nil lambda))))
4499 (assert (eql check cell-note))
4500 (if check
4501 (assert
4502 (eq :ok
4503 (handler-case
4504 (dolist (arg args nil)
4505 (setf fun (funcall fun arg)))
4506 (sb-int:simple-control-error (e)
4507 (when (equal
4508 (simple-condition-format-control e)
4509 "attempt to RETURN-FROM a block or GO to a tag that no longer exists")
4510 :ok)))))
4511 (ctu:assert-no-consing (apply fun args))))))
4512 (test nil `(lambda (x)
4513 (declare (optimize speed))
4514 (block out
4515 (flet ((ex () (return-from out 'out!)))
4516 (typecase x
4517 (cons (or (car x) (ex)))
4518 (t (ex)))))) :foo)
4519 (test t `(lambda (x)
4520 (declare (optimize speed))
4521 (funcall
4522 (block nasty
4523 (flet ((oops () (return-from nasty t)))
4524 #'oops)))) t)
4525 (test t `(lambda (r)
4526 (declare (optimize speed))
4527 (block out
4528 (flet ((ex () (return-from out r)))
4529 (lambda (x)
4530 (typecase x
4531 (cons (or (car x) (ex)))
4532 (t (ex))))))) t t)
4533 (test t `(lambda (x)
4534 (declare (optimize speed))
4535 (flet ((eh (x)
4536 (flet ((meh () (return-from eh 'meh)))
4537 (lambda ()
4538 (typecase x
4539 (cons (or (car x) (meh)))
4540 (t (meh)))))))
4541 (funcall (eh x)))) t t)))
4543 (with-test (:name (:bug-1050768 :symptom))
4544 ;; Used to signal an error.
4545 (compile nil
4546 `(lambda (string position)
4547 (char string position)
4548 (array-in-bounds-p string (1+ position)))))
4550 (with-test (:name (:bug-1050768 :cause))
4551 (let ((types `((string string)
4552 ((or (simple-array character 24) (vector t 24))
4553 (or (simple-array character 24) (vector t))))))
4554 (dolist (pair types)
4555 (destructuring-bind (orig conservative) pair
4556 (assert sb-c::(type= (specifier-type cl-user::conservative)
4557 (conservative-type (specifier-type cl-user::orig))))))))
4559 (with-test (:name (:smodular64 :wrong-width))
4560 (let ((fun (compile nil
4561 '(lambda (x)
4562 (declare (type (signed-byte 64) x))
4563 (sb-c::mask-signed-field 64 (- x 7033717698976965573))))))
4564 (assert (= (funcall fun 10038) -7033717698976955535))))
4566 (with-test (:name (:smodular32 :wrong-width))
4567 (let ((fun (compile nil '(lambda (x)
4568 (declare (type (signed-byte 31) x))
4569 (sb-c::mask-signed-field 31 (- x 1055131947))))))
4570 (assert (= (funcall fun 10038) -1055121909))))
4572 (with-test (:name :first-open-coded)
4573 (let ((fun (compile nil `(lambda (x) (first x)))))
4574 (assert (not (ctu:find-named-callees fun)))))
4576 (with-test (:name :second-open-coded)
4577 (let ((fun (compile nil `(lambda (x) (second x)))))
4578 (assert (not (ctu:find-named-callees fun)))))
4580 (with-test (:name :svref-of-symbol-macro)
4581 (compile nil `(lambda (x)
4582 (symbol-macrolet ((sv x))
4583 (values (svref sv 0) (setf (svref sv 0) 99))))))
4585 ;; The compiler used to update the receiving LVAR's type too
4586 ;; aggressively when converting a large constant to a smaller
4587 ;; (potentially signed) one, causing other branches to be
4588 ;; inferred as dead.
4589 (with-test (:name :modular-cut-constant-to-width)
4590 (let ((test (compile nil
4591 `(lambda (x)
4592 (logand 254
4593 (case x
4594 ((3) x)
4595 ((2 2 0 -2 -1 2) 9223372036854775803)
4596 (t 358458651)))))))
4597 (assert (= (funcall test -10470605025) 26))))
4599 (with-test (:name :append-type-derivation)
4600 (let ((test-cases
4601 '((lambda () (append 10)) (integer 10 10)
4602 (lambda () (append nil 10)) (integer 10 10)
4603 (lambda (x) (append x 10)) (or (integer 10 10) cons)
4604 (lambda (x) (append x (cons 1 2))) cons
4605 (lambda (x y) (append x (cons 1 2) y)) cons
4606 (lambda (x y) (nconc x (the list y) x)) t
4607 (lambda (x y) (nconc (the atom x) y)) t
4608 (lambda (x y) (nconc (the (or null (eql 10)) x) y)) t
4609 (lambda (x y) (nconc (the (or cons vector) x) y)) cons
4610 (lambda (x y) (nconc (the sequence x) y)) t
4611 (lambda (x y) (print (length y)) (append x y)) sequence
4612 (lambda (x y) (print (length y)) (append x y)) sequence
4613 (lambda (x y) (append (the (member (a) (b)) x) y)) cons
4614 (lambda (x y) (append (the (member (a) (b) c) x) y)) cons
4615 (lambda (x y) (append (the (member (a) (b) nil) x) y)) t)))
4616 (loop for (function result-type) on test-cases by #'cddr
4617 do (assert (sb-kernel:type= (sb-kernel:specifier-type
4618 (car (cdaddr (sb-kernel:%simple-fun-type
4619 (compile nil function)))))
4620 (sb-kernel:specifier-type result-type))))))
4622 (with-test (:name :bug-504121)
4623 (compile nil `(lambda (s)
4624 (let ((p1 #'upper-case-p))
4625 (funcall
4626 (lambda (g)
4627 (funcall p1 g))))
4628 (let ((p2 #'(lambda (char) (upper-case-p char))))
4629 (funcall p2 s)))))
4631 (with-test (:name (:bug-504121 :optional-missing))
4632 (compile nil `(lambda (s)
4633 (let ((p1 #'upper-case-p))
4634 (funcall
4635 (lambda (g &optional x)
4636 (funcall p1 g))))
4637 (let ((p2 #'(lambda (char) (upper-case-p char))))
4638 (funcall p2 s)))))
4640 (with-test (:name (:bug-504121 :optional-superfluous))
4641 (compile nil `(lambda (s)
4642 (let ((p1 #'upper-case-p))
4643 (funcall
4644 (lambda (g &optional x)
4645 (funcall p1 g))
4646 #\1 2 3))
4647 (let ((p2 #'(lambda (char) (upper-case-p char))))
4648 (funcall p2 s)))))
4650 (with-test (:name (:bug-504121 :key-odd))
4651 (compile nil `(lambda (s)
4652 (let ((p1 #'upper-case-p))
4653 (funcall
4654 (lambda (g &key x)
4655 (funcall p1 g))
4656 #\1 :x))
4657 (let ((p2 #'(lambda (char) (upper-case-p char))))
4658 (funcall p2 s)))))
4660 (with-test (:name (:bug-504121 :key-unknown))
4661 (compile nil `(lambda (s)
4662 (let ((p1 #'upper-case-p))
4663 (funcall
4664 (lambda (g &key x)
4665 (funcall p1 g))
4666 #\1 :y 2))
4667 (let ((p2 #'(lambda (char) (upper-case-p char))))
4668 (funcall p2 s)))))
4670 (with-test (:name :bug-1181684)
4671 (compile nil `(lambda ()
4672 (let ((hash #xD13CCD13))
4673 (setf hash (logand most-positive-word
4674 (ash hash 5)))))))
4676 (with-test (:name (:local-&optional-recursive-inline :bug-1180992))
4677 (compile nil
4678 `(lambda ()
4679 (labels ((called (&optional a))
4680 (recursed (&optional b)
4681 (called)
4682 (recursed)))
4683 (declare (inline recursed called))
4684 (recursed)))))
4686 (with-test (:name :constant-fold-logtest)
4687 (assert (equal (sb-kernel:%simple-fun-type
4688 (compile nil `(lambda (x)
4689 (declare (type (mod 1024) x)
4690 (optimize speed))
4691 (logtest x 2048))))
4692 '(function ((unsigned-byte 10)) (values null &optional)))))
4694 ;; type mismatches on LVARs with multiple potential sources used to
4695 ;; be reported as mismatches with the value NIL. Make sure we get
4696 ;; a warning, but that it doesn't complain about a constant NIL ...
4697 ;; of type FIXNUM.
4698 (with-test (:name (:multiple-use-lvar-interpreted-as-NIL :cast))
4699 (block nil
4700 (handler-bind ((sb-int:type-warning
4701 (lambda (c)
4702 (assert
4703 (not (search "Constant "
4704 (simple-condition-format-control
4705 c))))
4706 (return))))
4707 (compile nil `(lambda (x y z)
4708 (declare (type fixnum y z))
4709 (aref (if x y z) 0))))
4710 (error "Where's my warning?")))
4712 (with-test (:name (:multiple-use-lvar-interpreted-as-NIL catch))
4713 (block nil
4714 (handler-bind ((style-warning
4715 (lambda (c)
4716 (assert
4717 (not (position
4719 (simple-condition-format-arguments c))))
4720 (return))))
4721 (compile nil `(lambda (x y z f)
4722 (declare (type fixnum y z))
4723 (catch (if x y z) (funcall f)))))
4724 (error "Where's my style-warning?")))
4726 ;; Smoke test for rightward shifts
4727 (with-test (:name (:ash/right-signed))
4728 (let* ((f (compile nil `(lambda (x y)
4729 (declare (type (mod ,(* 2 sb-vm:n-word-bits)) y)
4730 (type sb-vm:signed-word x)
4731 (optimize speed))
4732 (ash x (- y)))))
4733 (max (ash most-positive-word -1))
4734 (min (- -1 max)))
4735 (flet ((test (x y)
4736 (assert (= (ash x (- y))
4737 (funcall f x y)))))
4738 (dotimes (x 32)
4739 (dotimes (y (* 2 sb-vm:n-word-bits))
4740 (test x y)
4741 (test (- x) y)
4742 (test (- max x) y)
4743 (test (+ min x) y))))))
4745 (with-test (:name (:ash/right-unsigned))
4746 (let ((f (compile nil `(lambda (x y)
4747 (declare (type (mod ,(* 2 sb-vm:n-word-bits)) y)
4748 (type word x)
4749 (optimize speed))
4750 (ash x (- y)))))
4751 (max most-positive-word))
4752 (flet ((test (x y)
4753 (assert (= (ash x (- y))
4754 (funcall f x y)))))
4755 (dotimes (x 32)
4756 (dotimes (y (* 2 sb-vm:n-word-bits))
4757 (test x y)
4758 (test (- max x) y))))))
4760 (with-test (:name (:ash/right-fixnum))
4761 (let ((f (compile nil `(lambda (x y)
4762 (declare (type (mod ,(* 2 sb-vm:n-word-bits)) y)
4763 (type fixnum x)
4764 (optimize speed))
4765 (ash x (- y))))))
4766 (flet ((test (x y)
4767 (assert (= (ash x (- y))
4768 (funcall f x y)))))
4769 (dotimes (x 32)
4770 (dotimes (y (* 2 sb-vm:n-word-bits))
4771 (test x y)
4772 (test (- x) y)
4773 (test (- most-positive-fixnum x) y)
4774 (test (+ most-negative-fixnum x) y))))))
4776 ;; expected failure
4777 (with-test (:name :fold-index-addressing-positive-offset)
4778 (let ((f (compile nil `(lambda (i)
4779 (if (typep i '(integer -31 31))
4780 (aref #. (make-array 63) (+ i 31))
4781 (error "foo"))))))
4782 (funcall f -31)))
4784 ;; 5d3a728 broke something like this in CL-PPCRE
4785 (with-test (:name :fold-index-addressing-potentially-negative-index)
4786 (compile nil `(lambda (index vector)
4787 (declare (optimize speed (safety 0))
4788 ((simple-array character (*)) vector)
4789 ((unsigned-byte 24) index))
4790 (aref vector (1+ (mod index (1- (length vector))))))))
4792 (with-test (:name :constant-fold-ash/right-fixnum)
4793 (compile nil `(lambda (a b)
4794 (declare (type fixnum a)
4795 (type (integer * -84) b))
4796 (ash a b))))
4798 (with-test (:name :constant-fold-ash/right-word)
4799 (compile nil `(lambda (a b)
4800 (declare (type word a)
4801 (type (integer * -84) b))
4802 (ash a b))))
4804 (with-test (:name :nconc-derive-type)
4805 (let ((function (compile nil `(lambda (x y)
4806 (declare (type (or cons fixnum) x))
4807 (nconc x y)))))
4808 (assert (equal (sb-kernel:%simple-fun-type function)
4809 '(function ((or cons fixnum) t) (values cons &optional))))))
4811 ;; make sure that all data-vector-ref-with-offset VOPs are either
4812 ;; specialised on a 0 offset or accept signed indices
4813 (with-test (:name :data-vector-ref-with-offset-signed-index)
4814 (let ((dvr (find-symbol "DATA-VECTOR-REF-WITH-OFFSET" "SB-KERNEL")))
4815 (when dvr
4816 (assert
4817 (null
4818 (loop for info in (sb-c::fun-info-templates
4819 (sb-c::fun-info-or-lose dvr))
4820 for (nil second-arg third-arg) = (sb-c::vop-info-arg-types info)
4821 unless (or (typep second-arg '(cons (eql :constant)))
4822 (find '(integer 0 0) third-arg :test 'equal)
4823 (equal second-arg
4824 `(:or ,(sb-c::primitive-type-or-lose
4825 'sb-vm::positive-fixnum)
4826 ,(sb-c::primitive-type-or-lose
4827 'fixnum))))
4828 collect info))))))
4830 (with-test (:name :data-vector-set-with-offset-signed-index)
4831 (let ((dvr (find-symbol "DATA-VECTOR-SET-WITH-OFFSET" "SB-KERNEL")))
4832 (when dvr
4833 (assert
4834 (null
4835 (loop for info in (sb-c::fun-info-templates
4836 (sb-c::fun-info-or-lose dvr))
4837 for (nil second-arg third-arg) = (sb-c::vop-info-arg-types info)
4838 unless (or (typep second-arg '(cons (eql :constant)))
4839 (find '(integer 0 0) third-arg :test 'equal)
4840 (equal second-arg
4841 `(:or ,(sb-c::primitive-type-or-lose
4842 'sb-vm::positive-fixnum)
4843 ,(sb-c::primitive-type-or-lose
4844 'fixnum))))
4845 collect info))))))
4847 (with-test (:name :maybe-inline-ref-to-dead-lambda)
4848 (compile nil `(lambda (string)
4849 (declare (optimize speed (space 0)))
4850 (cond ((every #'digit-char-p string)
4851 nil)
4852 ((some (lambda (c)
4853 (digit-char-p c))
4854 string))))))
4856 ;; the x87 backend used to sometimes signal FP errors during boxing,
4857 ;; because converting between double and single float values was a
4858 ;; noop (fixed), and no doubt many remaining issues. We now store
4859 ;; the value outside pseudo-atomic, so any SIGFPE should be handled
4860 ;; corrrectly.
4862 ;; When it fails, this test lands into ldb.
4863 (with-test (:name :no-overflow-during-allocation)
4864 (handler-case (eval '(cosh 90))
4865 (floating-point-overflow ()
4866 t)))
4868 ;; unbounded integer types could break integer arithmetic.
4869 (with-test (:name :bug-1199127)
4870 (compile nil `(lambda (b)
4871 (declare (type (integer -1225923945345 -832450738898) b))
4872 (declare (optimize (speed 3) (space 3) (safety 2)
4873 (debug 0) (compilation-speed 1)))
4874 (loop for lv1 below 3
4875 sum (logorc2
4876 (if (>= 0 lv1)
4877 (ash b (min 25 lv1))
4879 -2)))))
4881 ;; non-trivial modular arithmetic operations would evaluate to wider results
4882 ;; than expected, and never be cut to the right final bitwidth.
4883 (with-test (:name :bug-1199428-1)
4884 (let ((f1 (compile nil `(lambda (a c)
4885 (declare (type (integer -2 1217810089) a))
4886 (declare (type (integer -6895591104928 -561736648588) c))
4887 (declare (optimize (speed 2) (space 0) (safety 2) (debug 0)
4888 (compilation-speed 3)))
4889 (logandc1 (gcd c)
4890 (+ (- a c)
4891 (loop for lv2 below 1 count t))))))
4892 (f2 (compile nil `(lambda (a c)
4893 (declare (notinline - + gcd logandc1))
4894 (declare (optimize (speed 1) (space 1) (safety 0) (debug 1)
4895 (compilation-speed 3)))
4896 (logandc1 (gcd c)
4897 (+ (- a c)
4898 (loop for lv2 below 1 count t)))))))
4899 (let ((a 530436387)
4900 (c -4890629672277))
4901 (assert (eql (funcall f1 a c)
4902 (funcall f2 a c))))))
4904 (with-test (:name :bug-1199428-2)
4905 (let ((f1 (compile nil `(lambda (a b)
4906 (declare (type (integer -1869232508 -6939151) a))
4907 (declare (type (integer -11466348357 -2645644006) b))
4908 (declare (optimize (speed 1) (space 0) (safety 2) (debug 2)
4909 (compilation-speed 2)))
4910 (logand (lognand a -6) (* b -502823994)))))
4911 (f2 (compile nil `(lambda (a b)
4912 (logand (lognand a -6) (* b -502823994))))))
4913 (let ((a -1491588365)
4914 (b -3745511761))
4915 (assert (eql (funcall f1 a b)
4916 (funcall f2 a b))))))
4918 ;; win32 is very specific about the order in which catch blocks
4919 ;; must be allocated on the stack
4920 (with-test (:name :bug-1072739)
4921 (let ((f (compile nil
4922 `(lambda ()
4923 (STRING=
4924 (LET ((% 23))
4925 (WITH-OUTPUT-TO-STRING (G13908)
4926 (PRINC
4927 (LET ()
4928 (DECLARE (OPTIMIZE (SB-EXT:INHIBIT-WARNINGS 3)))
4929 (HANDLER-CASE
4930 (WITH-OUTPUT-TO-STRING (G13909) (PRINC %A%B% G13909) G13909)
4931 (UNBOUND-VARIABLE NIL
4932 (HANDLER-CASE
4933 (WITH-OUTPUT-TO-STRING (G13914)
4934 (PRINC %A%B% G13914)
4935 (PRINC "" G13914)
4936 G13914)
4937 (UNBOUND-VARIABLE NIL
4938 (HANDLER-CASE
4939 (WITH-OUTPUT-TO-STRING (G13913)
4940 (PRINC %A%B G13913)
4941 (PRINC "%" G13913)
4942 G13913)
4943 (UNBOUND-VARIABLE NIL
4944 (HANDLER-CASE
4945 (WITH-OUTPUT-TO-STRING (G13912)
4946 (PRINC %A% G13912)
4947 (PRINC "b%" G13912)
4948 G13912)
4949 (UNBOUND-VARIABLE NIL
4950 (HANDLER-CASE
4951 (WITH-OUTPUT-TO-STRING (G13911)
4952 (PRINC %A G13911)
4953 (PRINC "%b%" G13911)
4954 G13911)
4955 (UNBOUND-VARIABLE NIL
4956 (HANDLER-CASE
4957 (WITH-OUTPUT-TO-STRING (G13910)
4958 (PRINC % G13910)
4959 (PRINC "a%b%" G13910)
4960 G13910)
4961 (UNBOUND-VARIABLE NIL
4962 (ERROR "Interpolation error in \"%a%b%\"
4963 "))))))))))))))
4964 G13908)))
4965 "23a%b%")))))
4966 (assert (funcall f))))
4968 (with-test (:name :equal-equalp-transforms)
4969 (let* ((s "foo")
4970 (bit-vector #*11001100)
4971 (values `(nil 1 2 "test"
4972 ;; Floats duplicated here to ensure we get newly created instances
4973 (read-from-string "1.1") (read-from-string "1.2d0")
4974 (read-from-string "1.1") (read-from-string "1.2d0")
4975 1.1 1.2d0 '("foo" "bar" "test")
4976 #(1 2 3 4) #*101010 (make-broadcast-stream) #p"/tmp/file"
4977 ,s (copy-seq ,s) ,bit-vector (copy-seq ,bit-vector)
4978 ,(make-hash-table) #\a #\b #\A #\C
4979 ,(make-random-state) 1/2 2/3)))
4980 ;; Test all permutations of different types
4981 (assert
4982 (loop
4983 for x in values
4984 always (loop
4985 for y in values
4986 always
4987 (and (eq (funcall (compile nil `(lambda (x y)
4988 (equal (the ,(type-of x) x)
4989 (the ,(type-of y) y))))
4990 x y)
4991 (equal x y))
4992 (eq (funcall (compile nil `(lambda (x y)
4993 (equalp (the ,(type-of x) x)
4994 (the ,(type-of y) y))))
4995 x y)
4996 (equalp x y))))))
4997 (assert
4998 (funcall (compile
5000 `(lambda (x y)
5001 (equal (the (cons (or simple-bit-vector simple-base-string))
5003 (the (cons (or (and bit-vector (not simple-array))
5004 (simple-array character (*))))
5005 y))))
5006 (list (string 'list))
5007 (list "LIST")))
5008 (assert
5009 (funcall (compile
5011 `(lambda (x y)
5012 (equalp (the (cons (or simple-bit-vector simple-base-string))
5014 (the (cons (or (and bit-vector (not simple-array))
5015 (simple-array character (*))))
5016 y))))
5017 (list (string 'list))
5018 (list "lisT")))))
5020 (with-test (:name (restart-case optimize speed compiler-note)
5021 ;; Cannot-DX note crashes test driver unless we have this:
5022 :skipped-on '(not :stack-allocatable-fixed-objects))
5023 (handler-bind ((compiler-note #'error))
5024 (compile nil '(lambda ()
5025 (declare (optimize speed))
5026 (restart-case () (c ()))))
5027 (compile nil '(lambda ()
5028 (declare (optimize speed))
5029 (let (x)
5030 (restart-case (setf x (car (compute-restarts)))
5031 (c ()))
5032 x)))))
5034 (with-test (:name :copy-more-arg
5035 :fails-on '(not (or :x86 :x86-64 :arm :arm64)))
5036 ;; copy-more-arg might not copy in the right direction
5037 ;; when there are more fixed args than stack frame slots,
5038 ;; and thus end up splatting a single argument everywhere.
5039 ;; Failing platforms still start their stack frames at 8 slots, so
5040 ;; this is less likely to happen.
5041 (let ((limit 33))
5042 (labels ((iota (n)
5043 (loop for i below n collect i))
5044 (test-function (function skip)
5045 ;; function should just be (subseq x skip)
5046 (loop for i from skip below (+ skip limit) do
5047 (let* ((values (iota i))
5048 (f (apply function values))
5049 (subseq (subseq values skip)))
5050 (assert (equal f subseq)))))
5051 (make-function (n)
5052 (let ((gensyms (loop for i below n collect (gensym))))
5053 (compile nil `(lambda (,@gensyms &rest rest)
5054 (declare (ignore ,@gensyms))
5055 rest)))))
5056 (dotimes (i limit)
5057 (test-function (make-function i) i)))))
5059 (with-test (:name :apply-aref)
5060 (flet ((test (form)
5061 (let (warning)
5062 (handler-bind ((warning (lambda (c) (setf warning c))))
5063 (compile nil `(lambda (x y) (setf (apply #'sbit x y) 10))))
5064 (assert (not warning)))))
5065 (test `(lambda (x y) (setf (apply #'aref x y) 21)))
5066 (test `(lambda (x y) (setf (apply #'bit x y) 1)))
5067 (test `(lambda (x y) (setf (apply #'sbit x y) 0)))))
5069 (with-test (:name :warn-on-the-values-constant)
5070 (multiple-value-bind (fun warnings-p failure-p)
5071 (compile nil
5072 ;; The compiler used to elide this test without
5073 ;; noting that the type demands multiple values.
5074 '(lambda () (the (values fixnum fixnum) 1)))
5075 (declare (ignore warnings-p))
5076 (assert (functionp fun))
5077 (assert failure-p)))
5079 ;; quantifiers shouldn't cons themselves.
5080 (with-test (:name :quantifiers-no-consing
5081 :skipped-on '(or :interpreter
5082 (not :stack-allocatable-closures)))
5083 (let ((constantly-t (lambda (x) x t))
5084 (constantly-nil (lambda (x) x nil))
5085 (list (make-list 1000 :initial-element nil))
5086 (vector (make-array 1000 :initial-element nil)))
5087 (macrolet ((test (quantifier)
5088 (let ((function (make-symbol (format nil "TEST-~A" quantifier))))
5089 `(flet ((,function (function sequence)
5090 (,quantifier function sequence)))
5091 (ctu:assert-no-consing (,function constantly-t list))
5092 (ctu:assert-no-consing (,function constantly-nil vector))))))
5093 (test some)
5094 (test every)
5095 (test notany)
5096 (test notevery))))
5098 (with-test (:name :propagate-complex-type-tests)
5099 (flet ((test (type value)
5100 (let ((ftype (sb-kernel:%simple-fun-type
5101 (checked-compile `(lambda (x)
5102 (if (typep x ',type)
5104 ',value))))))
5105 (assert (typep ftype `(cons (eql function))))
5106 (assert (= 3 (length ftype)))
5107 (let* ((return (third ftype))
5108 (rtype (second return)))
5109 (assert (typep return `(cons (eql values)
5110 (cons t
5111 (cons (eql &optional)
5112 null)))))
5113 (assert (and (subtypep rtype type)
5114 (subtypep type rtype)))))))
5115 (mapc (lambda (params)
5116 (apply #'test params))
5117 `(((unsigned-byte 17) 0)
5118 ((member 1 3 5 7) 5)
5119 ((or symbol (eql 42)) t)))))
5121 (with-test (:name :constant-fold-complex-type-tests)
5122 (assert (equal (sb-kernel:%simple-fun-type
5123 (checked-compile `(lambda (x)
5124 (if (typep x '(member 1 3))
5125 (typep x '(member 1 3 15))
5126 t))))
5127 `(function (t) (values (member t) &optional))))
5128 (assert (equal (sb-kernel:%simple-fun-type
5129 (checked-compile `(lambda (x)
5130 (declare (type (member 1 3) x))
5131 (typep x '(member 1 3 15)))))
5132 `(function ((or (integer 1 1) (integer 3 3)))
5133 (values (member t) &optional)))))
5135 (with-test (:name :quietly-row-major-index-no-dimensions)
5136 (checked-compile `(lambda (x) (array-row-major-index x))))
5138 (with-test (:name :array-rank-transform)
5139 (checked-compile `(lambda (a) (array-rank (the an-imaginary-type a)))
5140 :allow-style-warnings t))
5142 (with-test (:name (:array-rank-fold :bug-1252108))
5143 (let ((notes (nth-value
5144 4 (checked-compile
5145 `(lambda (a)
5146 (typecase a
5147 ((array t 2)
5148 (when (= (array-rank a) 3)
5149 (array-dimension a 2)))))))))
5150 (assert (= 1 (length notes)))))
5152 (assert-error (upgraded-array-element-type 'an-undefined-type))
5154 (with-test (:name :xchg-misencoding)
5155 (assert (eql (funcall (checked-compile
5156 `(lambda (a b)
5157 (declare (optimize (speed 3) (safety 2))
5158 (type single-float a))
5159 (unless (eql b 1/2)
5160 (min a -1f0))))
5161 0f0 1)
5162 -1f0)))
5164 (with-test (:name :malformed-declare)
5165 (assert (nth-value
5166 1 (checked-compile `(lambda (x)
5167 (declare (unsigned-byte (x)))
5169 :allow-failure t))))
5171 (with-test (:name :no-dubious-asterisk-warning)
5172 (checked-compile
5173 `(lambda (foo)
5174 (macrolet ((frob-some-stuff (&rest exprs)
5175 (let ((temps
5176 (mapcar
5177 (lambda (x)
5178 (if (symbolp x) (copy-symbol x) (gensym)))
5179 exprs)))
5180 `(let ,(mapcar #'list temps exprs)
5181 (if (and ,@temps)
5182 (format t "Got~@{ ~S~^ and~}~%" ,@temps))))))
5183 (frob-some-stuff *print-base* (car foo))))))
5185 (with-test (:name :interr-type-specifier-hashing)
5186 (let ((specifiers
5187 (remove
5188 'simple-vector
5189 (map 'list
5190 (lambda (saetp)
5191 (sb-c::type-specifier
5192 (sb-c::specifier-type
5193 `(simple-array ,(sb-vm:saetp-specifier saetp) (*)))))
5194 sb-vm:*specialized-array-element-type-properties*))))
5195 (assert (sb-c::%interr-symbol-for-type-spec `(or ,@specifiers)))
5196 (assert (sb-c::%interr-symbol-for-type-spec
5197 `(or ,@specifiers system-area-pointer)))))
5199 (with-test (:name :simple-rank-1-array-*-p-works)
5200 (assert (funcall (checked-compile
5201 `(lambda () (typep #() '(simple-array * (*)))))))
5202 (loop for saetp across sb-vm:*specialized-array-element-type-properties*
5204 (dotimes (n-dimensions 3) ; test ranks 0, 1, and 2.
5205 (let ((dims (make-list n-dimensions :initial-element 2)))
5206 (dolist (adjustable-p '(nil t))
5207 (let ((a (make-array dims :element-type (sb-vm:saetp-specifier saetp)
5208 :adjustable adjustable-p)))
5209 (assert (eq (and (= n-dimensions 1) (not adjustable-p))
5210 (typep a '(simple-array * (*)))))))))))
5212 (with-test (:name :array-subtype-tests
5213 :skipped-on '(:not (:or :x86 :x86-64)))
5214 (assert (funcall (checked-compile
5215 `(lambda ()
5216 (typep #() '(or simple-vector simple-string))))))
5217 (flet ((approx-lines-of-assembly-code (type-expr)
5218 (count #\Newline
5219 (with-output-to-string (s)
5220 (disassemble
5221 `(lambda (x)
5222 (declare (optimize (sb-c::verify-arg-count 0)))
5223 (typep x ',type-expr))
5224 :stream s)))))
5225 ;; These are fragile, but less bad than the possibility of messing up
5226 ;; any vops, especially since the generic code in 'vm-type' checks for
5227 ;; a vop by its name in a place that would otherwise be agnostic of the
5228 ;; backend were it not for my inability to test all platforms.
5229 (assert (< (approx-lines-of-assembly-code
5230 '(simple-array * (*))) 25))
5231 ;; this tested all possible widetags one at a time, e.g. in VECTOR-SAP
5232 (assert (< (approx-lines-of-assembly-code
5233 '(sb-kernel:simple-unboxed-array (*))) 25))
5234 ;; This is actually a strange type but it's what ANSI-STREAM-READ-N-BYTES
5235 ;; declares as its buffer, which would choke in %BYTE-BLT if you gave it
5236 ;; (simple-array t (*)). But that's a different problem.
5237 (assert (< (approx-lines-of-assembly-code
5238 '(or system-area-pointer (simple-array * (*)))) 29))
5239 ;; And this was used by %BYTE-BLT which tested widetags one-at-a-time.
5240 (assert (< (approx-lines-of-assembly-code
5241 '(or system-area-pointer (sb-kernel:simple-unboxed-array (*))))
5242 29))))
5244 (with-test (:name :local-argument-mismatch-error-string)
5245 (multiple-value-bind (fun failurep warnings)
5246 (checked-compile `(lambda (x)
5247 (flet ((foo ()))
5248 (foo x)))
5249 :allow-warnings t)
5250 (declare (ignore failurep))
5251 (assert (= 1 (length warnings)))
5252 (multiple-value-bind (ok err) (ignore-errors (funcall fun 42))
5253 (assert (not ok))
5254 (assert (search "FLET FOO" (princ-to-string err))))))
5256 (with-test (:name :bug-1310574-0)
5257 (checked-compile `(lambda (a)
5258 (typecase a
5259 ((or (array * (* * 3)) (array * (* * 4)))
5260 (case (array-rank a)
5261 (2 (aref a 1 2))))))))
5263 (with-test (:name :bug-1310574-1)
5264 (checked-compile `(lambda (a)
5265 (typecase a
5266 ((or (array * ()) (array * (1)) (array * (1 2)))
5267 (case (array-rank a)
5268 (3 (aref a 1 2 3))))))))
5270 (with-test (:name :bug-573747)
5271 (assert (nth-value
5272 1 (checked-compile `(lambda (x) (progn (declare (integer x)) (* x 6)))
5273 :allow-failure t))))
5275 ;; Something in this function used to confuse lifetime analysis into
5276 ;; recording multiple conflicts for a single TNs in the dolist block.
5277 (with-test (:name :bug-1327008)
5278 (handler-bind (((or style-warning compiler-note)
5279 (lambda (c)
5280 (muffle-warning c))))
5281 (compile nil
5282 `(lambda (scheduler-spec
5283 schedule-generation-method
5284 utc-earliest-time utc-latest-time
5285 utc-other-earliest-time utc-other-latest-time
5286 &rest keys
5287 &key queue
5288 maximum-mileage
5289 maximum-extra-legs
5290 maximum-connection-time
5291 slice-number
5292 scheduler-hints
5293 permitted-route-locations prohibited-route-locations
5294 preferred-connection-locations disfavored-connection-locations
5295 origins destinations
5296 permitted-carriers prohibited-carriers
5297 permitted-operating-carriers prohibited-operating-carriers
5298 start-airports end-airports
5299 circuity-limit
5300 specified-circuity-limit-extra-miles
5301 (preferred-carriers :unspecified)
5302 &allow-other-keys)
5303 (declare (optimize speed))
5304 (let ((table1 (list nil))
5305 (table2 (list nil))
5306 (skip-flifo-checks (getf scheduler-spec :skip-flifo-checks))
5307 (construct-gaps-p (getf scheduler-spec :construct-gaps-p))
5308 (gap-locations (getf scheduler-spec :gap-locations))
5309 (result-array (make-array 100))
5310 (number-dequeued 0)
5311 (n-new 0)
5312 (n-calcs 0)
5313 (exit-reason 0)
5314 (prev-start-airports origins)
5315 (prev-end-airports destinations)
5316 (prev-permitted-carriers permitted-carriers))
5317 (flet ((run-with-hint (hint random-magic other-randomness
5318 maximum-extra-legs
5319 preferred-origins
5320 preferred-destinations
5321 same-pass-p)
5322 (let* ((hint-permitted-carriers (first hint))
5323 (preferred-end-airports
5324 (ecase schedule-generation-method
5325 (:DEPARTURE preferred-destinations)
5326 (:ARRIVAL preferred-origins)))
5327 (revised-permitted-carriers
5328 (cond ((and hint-permitted-carriers
5329 (not (eq permitted-carriers :ANY)))
5330 (intersection permitted-carriers
5331 hint-permitted-carriers))
5332 (hint-permitted-carriers)
5333 (permitted-carriers)))
5334 (revised-maximum-mileage
5335 (min (let ((maximum-mileage 0))
5336 (dolist (o start-airports)
5337 (dolist (d end-airports)
5338 (setf maximum-mileage
5339 (max maximum-mileage (mileage o d)))))
5340 (round (+ (* circuity-limit maximum-mileage)
5341 (or specified-circuity-limit-extra-miles
5342 (hairy-calculation slice-number)))))
5343 maximum-mileage)))
5344 (when (or (not (equal start-airports prev-start-airports))
5345 (not (equal end-airports prev-end-airports))
5346 (and (not (equal revised-permitted-carriers
5347 prev-permitted-carriers))))
5348 (incf n-calcs)
5349 (calculate-vectors
5350 prohibited-carriers
5351 permitted-operating-carriers
5352 prohibited-operating-carriers
5353 permitted-route-locations
5354 prohibited-route-locations
5355 construct-gaps-p
5356 gap-locations
5357 preferred-carriers)
5358 (setf prev-permitted-carriers revised-permitted-carriers))
5359 (multiple-value-bind (this-number-dequeued
5360 this-exit-reason
5361 this-n-new)
5362 (apply #'schedule-loop
5363 utc-earliest-time utc-other-earliest-time
5364 utc-latest-time utc-other-latest-time
5365 scheduler-spec schedule-generation-method
5366 queue
5367 :maximum-mileage revised-maximum-mileage
5368 :maximum-extra-legs maximum-extra-legs
5369 :maximum-connection-time maximum-connection-time
5370 :same-pass-p same-pass-p
5371 :preferred-end-airports preferred-end-airports
5372 :maximum-blah random-magic
5373 :skip-flifo-checks skip-flifo-checks
5374 :magic1 table1
5375 :magic2 table2
5376 :preferred-connection-locations preferred-connection-locations
5377 :disfavored-connection-locations disfavored-connection-locations
5378 keys)
5379 (when other-randomness
5380 (loop for i fixnum from n-new to (+ n-new (1- this-n-new))
5381 do (hairy-calculation i result-array)))
5382 (incf number-dequeued this-number-dequeued)
5383 (incf n-new this-n-new)
5384 (setq exit-reason (logior exit-reason this-exit-reason))))))
5385 (let ((n-hints-processed 0))
5386 (dolist (hint scheduler-hints)
5387 (run-with-hint hint n-hints-processed t 0
5388 nil nil nil)
5389 (incf n-hints-processed)))
5390 (run-with-hint nil 42 nil maximum-extra-legs
5391 '(yyy) '(xxx) t))
5392 exit-reason)))))
5394 (with-test (:name :dead-code-in-optional-dispatch)
5395 ;; the translation of each optional entry is
5396 ;; (let ((#:g (error "nope"))) (funcall #<clambda> ...))
5397 ;; but the funcall is unreachable. Since this is an artifact of how the
5398 ;; lambda is converted, it should not generate a note as if in user code.
5399 (checked-compile
5400 `(lambda (a &optional (b (error "nope")) (c (error "nope")))
5401 (values c b a))))
5403 (with-test (:name :nth-value-of-non-constant-N :skipped-on :interpreter)
5404 (labels ((foo (n f) (nth-value n (funcall f)))
5405 (bar () (values 0 1 2 3 4 5 6 7 8 9)))
5406 (assert (= (foo 5 #'bar) 5)) ; basic correctness
5407 (assert (eq (foo 12 #'bar) nil))
5408 (ctu:assert-no-consing (eql (foo 953 #'bar) 953))))
5410 (with-test (:name :position-derive-type-optimizer)
5411 (assert-code-deletion-note
5412 '(lambda (x) ; the call to POSITION can't return 4
5413 (let ((i (position x #(a b c d) :test 'eq)))
5414 (case i (4 'nope) (t 'okeydokey))))))
5416 ;; Assert that DO-PACKED-TNS has unsurprising behavior if the body RETURNs.
5417 ;; This isn't a test in the problem domain of CL - it's of an internal macro,
5418 ;; and x86-64-specific not because of broken-ness, but because it uses
5419 ;; known random TNs to play with. Printing "skipped on" for other backends
5420 ;; would be somewhat misleading in as much as it means nothing about
5421 ;; the correctness of the test on other architectures.
5422 #+x86-64
5423 (with-test (:name :do-packed-tn-iterator)
5424 (dotimes (i (ash 1 6))
5425 (labels ((make-tns (n)
5426 (mapcar 'copy-structure
5427 (subseq `sb-vm::(,rax-tn ,rbx-tn ,rcx-tn) 0 n)))
5428 (link (list)
5429 (when list
5430 (setf (sb-c::tn-next (car list)) (link (cdr list)))
5431 (car list))))
5432 (let* ((normal (make-tns (ldb (byte 2 0) i)))
5433 (restricted (make-tns (ldb (byte 2 2) i)))
5434 (wired (make-tns (ldb (byte 2 4) i)))
5435 (expect (append normal restricted wired))
5436 (comp (sb-c::make-empty-component))
5437 (ir2-comp (sb-c::make-ir2-component)))
5438 (setf (sb-c::component-info comp) ir2-comp
5439 (sb-c::ir2-component-normal-tns ir2-comp) (link normal)
5440 (sb-c::ir2-component-restricted-tns ir2-comp) (link restricted)
5441 (sb-c::ir2-component-wired-tns ir2-comp) (link wired))
5442 (let* ((list)
5443 (result (sb-c::do-packed-tns (tn comp 42) (push tn list))))
5444 (assert (eq result 42))
5445 (assert (equal expect (nreverse list))))
5446 (let* ((n 0) (list)
5447 (result (sb-c::do-packed-tns (tn comp 'bar)
5448 (push tn list)
5449 (if (= (incf n) 4) (return 'foo)))))
5450 (assert (eq result (if (>= (length expect) 4) 'foo 'bar)))
5451 (assert (equal (subseq expect 0 (min 4 (length expect)))
5452 (nreverse list))))))))
5454 ;; lp# 310267
5455 (with-test (:name (optimize :quality-multiply-specified :bug-310267))
5456 (let ((sb-c::*policy* sb-c::*policy*)) ; to keep this test pure
5457 (assert-signal (proclaim '(optimize space debug (space 0)))
5458 style-warning)
5459 (flet ((test (form)
5460 (assert (= 1 (length (nth-value
5461 3 (checked-compile
5462 form :allow-style-warnings t)))))))
5463 (test `(lambda () (declare (optimize speed (speed 0))) 5))
5464 (test `(lambda () (declare (optimize speed) (optimize (speed 0))) 5))
5465 (test `(lambda ()
5466 (declare (optimize speed)) (declare (optimize (speed 0)))
5467 5)))
5469 ;; these are OK
5470 (assert-no-signal (proclaim '(optimize (space 3) space)))
5471 (checked-compile `(lambda () (declare (optimize speed (speed 3))) 5))
5472 (checked-compile `(lambda () (declare (optimize speed) (optimize (speed 3))) 5))
5473 (checked-compile `(lambda ()
5474 (declare (optimize speed)) (declare (optimize (speed 3)))
5475 5))))
5477 (with-test (:name (truncate :type-derivation))
5478 (assert (= 4 (funcall (checked-compile
5479 `(lambda (a b)
5480 (truncate a (the (rational (1) (3)) b))))
5481 10 5/2))))
5483 (with-test (:name :constantp-on-a-literal-function-works)
5484 (assert (constantp `(the (function (list) t) ,#'car))))
5486 (with-test (:name :arg-count-error)
5487 (assert (eq :win (handler-case (funcall (intern "CONS") 1 2 3)
5488 (sb-int:simple-program-error () :win)
5489 (condition () :lose)))))
5491 (with-test (:name :mv-conversion)
5492 (checked-compile `(lambda (a)
5493 (tagbody (go 0)
5494 (list (unwind-protect a))
5495 (multiple-value-call #'list
5496 (values (catch 'ct5 (go 0))))
5497 0))))
5499 (with-test (:name (:null-cleanups-1 :bug-1416704 :bug-404441))
5500 (let ((x (funcall
5501 (checked-compile
5502 `(lambda ()
5503 (lambda (x)
5504 (declare (optimize speed))
5505 (if x
5506 (funcall (flet ((bar () 10)) #'bar))
5507 (funcall (flet ((fez ()
5508 (funcall (flet ((foo () 20)) #'foo))))
5509 #'fez)))))))))
5510 (assert (= (funcall x t) 10))
5511 (assert (= (funcall x nil) 20))))
5513 (with-test (:name (:null-cleanups-2 :bug-1416704 :bug-404441))
5514 (let ((fun (funcall
5515 (checked-compile
5516 `(lambda ()
5517 (lambda (x)
5518 (declare (optimize speed))
5519 (let* ((a2 (lambda () 20))
5520 (a4 (lambda ()))
5521 (a0 (flet ((f () (funcall a2)))
5522 #'f))
5523 (a3 (lambda ()
5524 (if x
5525 (if x
5526 (throw 'x 10)
5527 (let ((a5 (lambda () (funcall a4))))
5528 (funcall a5)))
5529 (funcall a0)))))
5530 (funcall a3))))))))
5531 (assert (= (catch 'x (funcall fun t)) 10))
5532 (assert (= (catch 'x (funcall fun nil)) 20))))
5535 (with-test (:name :locall-already-let-converted)
5536 (assert (eq (funcall
5537 (funcall
5538 (checked-compile
5539 `(lambda ()
5540 (flet ((call (ff)
5541 (flet ((f () (return-from f ff)))
5542 (declare (inline f))
5544 (f))))
5545 (declare (inline call))
5546 (call 1)
5547 (call (lambda () 'result)))))))
5548 'result)))
5550 (with-test (:name :debug-dump-elsewhere)
5551 (assert (eql (catch 'x
5552 (funcall
5553 (checked-compile
5554 `(lambda ()
5555 (declare (optimize debug))
5556 (throw 'x *)))))
5557 *)))
5559 (with-test (:name (typep :quasiquoted-constant))
5560 (assert (null (ctu:find-named-callees
5561 (checked-compile
5562 `(lambda (x)
5563 (typep x `(signed-byte ,sb-vm:n-word-bits))))))))
5565 (with-test (:name (logior :transform))
5566 (multiple-value-bind (fun failurep warnings)
5567 (checked-compile `(lambda (c)
5568 (flet ((f (x)
5569 (the integer x)))
5570 (logior c (f nil))))
5571 :allow-warnings t)
5572 (assert failurep)
5573 (assert (= 1 (length warnings)))
5574 (assert-error (funcall fun 10) type-error)))
5576 (with-test (:name :eql/integer-folding)
5577 (checked-compile
5578 `(lambda (a)
5579 (fceiling (the (member 2.3 21672589639883401935) a)))))
5581 (with-test (:name (position :derive-type))
5582 (let ((f (checked-compile
5583 `(lambda (x)
5584 (declare (type (simple-string 90) x))
5585 (declare (muffle-conditions code-deletion-note))
5586 (let ((b (position #\i x)))
5587 (if (and (integerp b) (> b 100))
5588 'yikes 'okey-dokey))))))
5589 ;; The function can not return YIKES
5590 (assert (not (ctu:find-code-constants f :type '(eql yikes))))))
5592 (with-test (:name :compile-file-error-position-reporting)
5593 (dolist (input '("data/wonky1.lisp" "data/wonky2.lisp" "data/wonky3.lisp"))
5594 (let ((expect (with-open-file (f input) (read f))))
5595 (assert (stringp expect))
5596 (let ((err-string (with-output-to-string (*error-output*)
5597 (compile-file input :print nil))))
5598 (assert (search expect err-string))))))
5600 (with-test (:name (coerce :derive-type))
5601 (macrolet ((check (type ll form &rest values)
5602 `(assert (equal (funcall (checked-compile
5603 `(lambda ,',ll
5604 (ctu:compiler-derived-type ,',form)))
5605 ,@values)
5606 ',type))))
5607 (check list
5609 (coerce a 'list)
5610 nil)
5611 (check (unsigned-byte 32)
5613 (coerce a '(unsigned-byte 32))
5615 (check character
5616 (a x)
5617 (coerce a (array-element-type (the (array character) x)))
5619 "abc")
5620 (check (unsigned-byte 32)
5621 (a x)
5622 (coerce a (array-element-type (the (array (unsigned-byte 32)) x)))
5624 (make-array 10 :element-type '(unsigned-byte 32)))))
5626 (with-test (:name :associate-args)
5627 (flet ((test (form argument)
5628 (multiple-value-bind (fun failurep warnings)
5629 (checked-compile form :allow-warnings t)
5630 (assert failurep)
5631 (assert (= 1 (length warnings)))
5632 (assert-error (funcall fun argument)))))
5633 (test `(lambda (x) (+ 1 x nil)) 2)
5634 (test `(lambda (x) (/ 1 x nil)) 4)))
5636 (with-test (:name :eager-substitute-single-use-lvar)
5637 (assert (= (funcall
5638 (compile nil
5639 `(lambda (a)
5640 (declare (optimize (debug 0) (safety 0)))
5641 (let ((a (the fixnum a))
5642 (x 1)
5644 (tagbody
5645 (flet ((jump () (go loop)))
5646 (jump))
5647 loop
5648 (setf z (the fixnum (if (= x 1) #xFFF a)))
5649 (unless (= x 0)
5650 (setf x 0)
5651 (go loop)))
5652 z)))
5653 2))))
5655 (with-test (:name :vop-on-eql-type)
5656 (assert (= (funcall
5657 (funcall (compile nil
5658 `(lambda (b)
5659 (declare ((eql -7) b)
5660 (optimize debug))
5661 (lambda (x)
5662 (logior x b))))
5665 -5)))
5667 (flet ((test (form)
5668 (multiple-value-bind (fun failurep)
5669 (checked-compile `(lambda () ,form)
5670 :allow-failure t)
5671 (assert failurep)
5672 (assert-error (funcall fun) sb-int:compiled-program-error))))
5674 (with-test (:name (compile macrolet :malformed))
5675 (test '(macrolet (foo () 'bar)))
5676 (test '(macrolet x))
5677 (test '(symbol-macrolet x))
5678 (test '(symbol-macrolet (x))))
5680 (with-test (:name (compile flet :malformed))
5681 (test '(flet (foo () 'bar)))
5682 (test '(flet x))
5683 (test '(labels (foo () 'bar)))
5684 (test '(labels x))))
5686 (with-test (:name :compile-load-time-value-interpreted-mode)
5687 ;; This test exercises the same pattern as HANDLER-BIND (to a
5688 ;; degree). In particular a HANDLER-BIND that was compiled when the
5689 ;; *EVALUATOR-MODE* was :INTERPRET would not compile its class
5690 ;; predicates, because LOAD-TIME-VALUE just called EVAL, and you
5691 ;; would get back a list with an interpreted function in it.
5693 ;; In the code below, this function when called would generate a new
5694 ;; symbol each time. But if the compiler processes the guts as it
5695 ;; should, you get back a compiled lambda which returns a constant
5696 ;; symbol.
5697 (let ((f (let ((sb-ext:*evaluator-mode* :interpret))
5698 (checked-compile
5699 `(lambda ()
5700 (load-time-value
5701 (list (lambda ()
5702 (macrolet ((foo ()
5703 (sb-int:keywordicate (gensym))))
5704 (foo))))))))))
5705 (eq (funcall (car (funcall f)))
5706 (funcall (car (funcall f))))))
5708 (with-test (:name :constant-fold-%eql/integer)
5709 (assert (null
5710 (funcall (checked-compile
5711 `(lambda (x)
5712 (declare (type (complex single-float) x)
5713 (optimize (debug 2)))
5714 (member (the (eql #c(0.0 0.0)) x)
5715 '(1 2 3 9912477572127105188))))
5716 #C(0.0 0.0)))))
5718 (with-test (:name (compile svref :constant))
5719 (assert
5720 (= (funcall (checked-compile
5721 `(lambda () (svref #(1 2 3) 1))))
5722 2)))
5724 (with-test (:name (compile char-equal :type-intersection))
5725 (assert
5726 (eq (funcall (checked-compile
5727 `(lambda (x y)
5728 (char-equal (the (member #\a #\B) x)
5729 (the (eql #\A) y))))
5730 #\a #\A)
5731 t)))
5733 (with-test (:name (oddp fixnum :no-consing))
5734 (let ((f (compile nil '(lambda (x) (oddp x)))))
5735 (ctu:assert-no-consing (funcall f most-positive-fixnum))))
5736 (with-test (:name (oddp bignum :no-consing))
5737 (let ((f (compile nil '(lambda (x) (oddp x))))
5738 (x (* most-positive-fixnum most-positive-fixnum 3)))
5739 (ctu:assert-no-consing (funcall f x))))
5740 (with-test (:name (logtest fixnum :no-consing :bug-1277690))
5741 (let ((f (compile nil '(lambda (x) (logtest x most-positive-fixnum)))))
5742 (ctu:assert-no-consing (funcall f 1))))
5743 (with-test (:name (logtest bignum :no-consing))
5744 (let ((f (compile nil '(lambda (x) (logtest x 1))))
5745 (x (* most-positive-fixnum most-positive-fixnum 3)))
5746 (ctu:assert-no-consing (funcall f x))))
5748 (with-test (:name (:randomized :mask-signed-field))
5749 (let (result)
5750 (dotimes (i 1000)
5751 (let* ((ool (compile nil '(lambda (s i) (sb-c::mask-signed-field s i))))
5752 (size (random (* sb-vm:n-word-bits 2)))
5753 (constant (compile nil `(lambda (i) (sb-c::mask-signed-field ,size i))))
5754 (arg (- (random (* most-positive-fixnum 8)) (* most-positive-fixnum 4)))
5755 (declared (compile nil `(lambda (i) (declare (type (integer ,(- (abs arg)) ,(abs arg)) i)) (sb-c::mask-signed-field ,size i))))
5756 (ool-answer (funcall ool size arg))
5757 (constant-answer (funcall constant arg))
5758 (declared-answer (funcall declared arg)))
5759 (unless (= ool-answer constant-answer declared-answer)
5760 (push (list size arg ool-answer constant-answer declared-answer) result))))
5761 (assert (null result))))
5763 (with-test (:name :array-dimensions-*)
5764 (= (funcall (compile nil `(lambda (array)
5765 (declare ((or (vector t) (array character)) array))
5766 (array-dimension array 0)))
5767 #(1 2 3))
5770 (with-test (:name :generate-type-checks-on-dead-blocks)
5771 (assert (equalp (funcall (compile nil `(lambda (a b)
5772 (declare (optimize (safety 3))
5773 (type (member vector 42) a))
5774 (map a 'list (the vector b) #*)))
5775 'vector #())
5776 #())))
5778 (with-test (:name (make-list :large 1))
5779 (checked-compile `(lambda ()
5780 (make-list (expt 2 28) :initial-element 0))))
5782 (with-test (:name (make-list :large 2)
5783 :skipped-on '(not :64-bit))
5784 (checked-compile `(lambda ()
5785 (make-list (expt 2 30) :initial-element 0))))
5787 (with-test (:name :bad-cond)
5788 (assert-error
5789 (checked-compile
5790 '(lambda () (cond (t 10) 20)))))
5792 (with-test (:name :removed-dx-cast)
5793 (assert (= (funcall
5794 (checked-compile `(lambda ()
5795 (loop
5796 (let ((x (the integer (return 0))))
5797 (declare (dynamic-extent x))
5798 (unwind-protect x 1))))))
5799 0)))
5801 (with-test (:name :isqrt-derivation)
5802 (assert (eql (funcall (checked-compile
5803 `(lambda (i)
5804 (isqrt (count (the bit i) #*11101))))
5806 2)))
5808 (with-test (:name :vector-zero-initialization)
5809 (assert (equalp (funcall (funcall (checked-compile
5810 `(lambda (x b)
5811 (declare ((eql 0) x)
5812 (optimize (debug 2)))
5813 (lambda ()
5814 (vector x (isqrt b)))))
5815 0 4))
5816 #(0 2))))
5818 (with-test (:name :cons-zero-initialization)
5819 (assert (equalp (funcall (funcall (checked-compile
5820 `(lambda (x b)
5821 (declare ((eql 0) x)
5822 (optimize (debug 2)))
5823 (lambda ()
5824 (cons x (isqrt b)))))
5825 0 4))
5826 '(0 . 2))))
5828 (with-test (:name :check-important-result-warning)
5829 (multiple-value-bind (fun failure warnings style-warnings)
5830 (checked-compile '(lambda (x z)
5831 (declare (notinline nintersection))
5832 (nintersection x z) x)
5833 :allow-style-warnings t)
5834 (declare (ignore fun failure warnings))
5835 (loop for c in style-warnings
5837 (assert (search "NINTERSECTION"
5838 (princ-to-string c))))))
5840 (with-test (:name :destroyed-constant-warning)
5841 (multiple-value-bind (fun failure warnings)
5842 (checked-compile '(lambda ()
5843 (declare (notinline nunion))
5844 (nunion '(1 2 3) '(1 2 4)))
5845 :allow-warnings t)
5846 (declare (ignore fun failure))
5847 (loop for c in warnings
5849 (assert (search "NUNION"
5850 (princ-to-string c))))))
5852 (with-test (:name :%array-data-vector-complex-type-derivation)
5853 (let ((type (funcall (checked-compile
5854 `(lambda (x)
5855 (ctu:compiler-derived-type (sb-kernel:%array-data-vector (the array x)))))
5856 #2A())))
5857 (assert (eq type 'array))))
5859 (with-test (:name :equalp-transofrm)
5860 (assert
5861 (funcall (checked-compile
5862 `(lambda (x y)
5863 (equalp (the (simple-array single-float (*)) x)
5864 (the (simple-array double-float (*)) y))))
5865 (coerce '(1f0) '(simple-array single-float (*)))
5866 (coerce '(1d0) '(simple-array double-float (*))))))
5868 (with-test (:name :array-hairy-type-derivation)
5869 (assert
5870 (equal (funcall (checked-compile
5871 `(lambda (x)
5872 (subseq (the (and (satisfies sb-impl::vector-with-fill-pointer-p)
5873 (string 3)) x)
5874 1)))
5875 (make-array 3 :element-type 'character
5876 :fill-pointer t
5877 :initial-contents "abc"))
5878 "bc")))
5880 (with-test (:name :nreverse-derive-type)
5881 (assert
5882 (not (funcall (checked-compile
5883 '(lambda (x)
5884 (eql (car (nreverse (the (cons (eql 10)) x))) 10)))
5885 '(10 20)))))
5887 (with-test (:name :subseq-derive-type)
5888 (assert
5889 (equalp (funcall (checked-compile
5890 '(lambda (x)
5891 (subseq (the (simple-vector 3) x) 1)))
5892 #(1 2 3))
5893 #(2 3))))
5895 (with-test (:name :sequence-derive-type)
5896 (assert
5897 (equalp (funcall (checked-compile
5898 '(lambda (x)
5899 (copy-seq (the (and string (not (simple-array nil))) x))))
5900 (make-array 3 :element-type 'character
5901 :fill-pointer 2
5902 :initial-contents "123"))
5903 "12")))
5905 (with-test (:name :sequence-derive-type.2)
5906 (assert
5907 (funcall (checked-compile
5908 '(lambda (x y)
5909 (equal (the (and string (not (simple-array nil))) x) y)))
5910 (make-array 3 :element-type 'character
5911 :fill-pointer 2
5912 :initial-contents "123")
5913 "12")))
5915 (with-test (:name :sequence-derive-type.3)
5916 (assert
5917 (equalp (funcall (checked-compile
5918 '(lambda (x)
5919 (subseq (the (or (simple-array * (*)) string) x) 0 2)))
5920 #(1 2 3))
5921 #(1 2))))
5923 (with-test (:name :not-enough-values-cast)
5924 (assert
5925 (not (funcall (checked-compile
5926 `(lambda ()
5927 (car (describe 1 (make-broadcast-stream)))))))))
5929 ;; Vestigial exit deletion was a bit too aggressive, causing stack
5930 ;; analysis to decide that the value of (BAR 10) in both cases below
5931 ;; needed to be nipped out from under the dynamic-extent allocation of
5932 ;; Y (or #'Y), which %NIP-VALUES refused to do (DX values must not be
5933 ;; moved once allocated).
5934 (with-test (:name (:exit-deletion :bug-1563127 :variable))
5935 (compile nil '(lambda (x)
5936 (block test
5937 (multiple-value-prog1 (bar 10)
5938 (let ((y (list x)))
5939 (declare (dynamic-extent y))
5940 (bar y)
5941 (if x
5942 (return-from test))))))))
5944 (with-test (:name (:exit-deletion :bug-1563127 :function))
5945 (compile nil '(lambda (x)
5946 (block test
5947 (multiple-value-prog1 (bar 10)
5948 (flet ((y () (list x)))
5949 (declare (dynamic-extent #'y))
5950 (bar #'y)
5951 (if x
5952 (return-from test))))))))
5954 (with-test (:name :mv-call-no-let-conversion)
5955 (assert (equal
5956 (funcall
5957 (checked-compile
5958 '(lambda ()
5959 (locally (declare (optimize (sb-c::let-conversion 0)))
5960 (multiple-value-call #'lisp-implementation-version (values))))))
5961 (lisp-implementation-version)))
5962 (assert (equal
5963 (funcall
5964 (checked-compile
5965 '(lambda ()
5966 (locally (declare (optimize (sb-c::let-conversion 0)))
5967 (multiple-value-call #'lisp-implementation-type (values))))))
5968 (lisp-implementation-type)))
5969 (assert (equal
5970 (funcall
5971 (checked-compile
5972 '(lambda ()
5973 (locally (declare (optimize (sb-c::let-conversion 0)))
5974 (multiple-value-call #'princ-to-string 1)))))
5975 "1")))
5977 (with-test (:name :mv-call-argument-mismatch)
5978 (assert
5979 (nth-value 2
5980 (checked-compile
5981 '(lambda () (multiple-value-call #'cons 1 2 3))
5982 :allow-warnings t))))
5984 (with-test (:name :valid-callable-argument-cast)
5985 (assert (equal (funcall (checked-compile '(lambda (x)
5986 (find-if (the function #'oddp)
5987 x)))
5988 '(2 4 3))
5989 3)))
5991 (with-test (:name :usigned-word-float-conversion)
5992 (assert (= (rational (funcall (checked-compile `(lambda (x)
5993 (float (the sb-ext:word x) 1d0)))
5994 sb-ext:most-positive-word))
5995 #+32-bit 4294967295
5996 #+64-bit 18446744073709551616)))
5998 (with-test (:name :callable-argument-mismatch-on-xep)
5999 (assert (= (funcall (checked-compile
6000 `(lambda (s x)
6001 (locally (declare (notinline reduce))
6002 (reduce (lambda (a b)
6003 (+ a b x))
6004 s))))
6005 '(1 2) 3)
6007 (assert (= (funcall (checked-compile
6008 `(lambda (s x)
6009 (locally (declare (notinline reduce))
6010 (reduce (lambda (&optional a b z)
6011 (declare (ignore z))
6012 (+ a b x))
6013 s))))
6014 '(1 2) 3)
6015 6)))
6017 (with-test (:name :mv-call-type-derivation
6018 :fails-on :sbcl)
6019 (assert (equal (funcall (checked-compile
6020 `(lambda (list)
6021 (multiple-value-call
6022 (lambda (&optional a &rest r)
6023 (declare (cons r)
6024 (ignore r))
6025 (list a))
6026 (values-list list)))
6027 :allow-warnings t)
6028 '(1 2))
6029 '(1))))
6031 (with-test (:name :delete-optional-dispatch-xep)
6032 (let ((name (gensym)))
6033 (assert (= (funcall (checked-compile `(sb-int:named-lambda ,name
6034 (&optional x)
6035 (if (= x 0)
6037 (multiple-value-call #',name (1- x)))))
6039 10))))
6041 (with-test (:name :yes-or-no-p-type)
6042 (checked-compile `(lambda ()
6043 (yes-or-no-p nil)))
6044 (checked-compile `(lambda ()
6045 (y-or-n-p nil)))
6046 (checked-compile `(lambda ()
6047 (yes-or-no-p #'list)))
6048 (checked-compile `(lambda ()
6049 (y-or-n-p #'list))))
6051 (with-test (:name :callable-delayed-mismatch)
6052 (multiple-value-bind (fun failure-p warnings)
6053 (checked-compile '(lambda () (let ((f 'cons)) (find-if f '(10))))
6054 :allow-warnings 'simple-warning)
6055 (declare (ignore fun))
6056 (assert failure-p)
6057 (assert (= (length warnings) 1))
6058 (search "The function CONS is called by"
6059 (princ-to-string (first warnings)))))
6061 (with-test (:name :set-type-conflict)
6062 (assert (nth-value 1
6063 (checked-compile
6064 '(lambda () (set '// 10))
6065 :allow-warnings t))))
6067 (with-test (:name :two-arg-funs-check)
6068 (loop for (nil x) in sb-c::*two-arg-functions*
6070 (assert (fboundp x))
6071 (assert (sb-int:info :function :info x))))
6073 (with-test (:name :two-arg-with-two-arguments-only)
6074 (assert (funcall (checked-compile `(lambda (x y) (string-lessp x y :start1 0)))
6076 "b")))
6078 (with-test (:name :optimize-functional-arguments-casts)
6079 (let ((fun (checked-compile
6080 '(lambda (list key)
6081 (declare (type atom key))
6082 (find 1 list :key (the (member car) key))))))
6083 (assert (equal (funcall fun '((a b) (1 a)) 'car)
6084 '(1 a)))
6085 (assert-error (equal (funcall fun '((a b) (1 a)) 'cdr)
6086 '(1 a)))))
6088 (with-test (:name :two-arg-rewriting-find-if)
6089 (assert (= (funcall (checked-compile
6090 `(lambda (x)
6091 (declare (type vector x))
6092 (find-if #'oddp x :key '-)))
6093 #(1))
6094 1)))
6096 (with-test (:name :transforms-check-policy-first)
6097 (assert (eql (funcall (checked-compile
6098 `(lambda (x)
6099 (declare (optimize speed space))
6100 (find x "a b c" :test #'char-equal))
6101 :allow-notes nil)
6102 #\B)
6103 #\b)))
6105 (with-test (:name (:valid-callable-argument :toplevel-xep))
6106 (assert (nth-value 2 (checked-compile `(lambda (l) (find-if (lambda ()) l))
6107 :allow-warnings t))))
6109 (with-test (:name (:valid-callable-argument :handler-bind))
6110 (assert (nth-value 2 (checked-compile
6111 `(lambda (l) (handler-bind ((error (lambda ()))) (funcall l)))
6112 :allow-warnings t))))