1 ;;;; various compiler tests without side effects
3 ;;;; This software is part of the SBCL system. See the README file for
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
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).
25 ;;; This test code is from Douglas Crosher's simplified TICKLE-BUG
26 ;;; (2000-09-06 on cmucl-imp).
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
49 ;;; Exercise a compiler bug (by crashing the compiler).
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
)
58 (block used-by-some-y?
62 (return-from used-by-some-y? t
)))))
63 (declare (inline frob
))
67 :allow-style-warnings t
)
68 (declare (ignore failure-p warnings
))
69 (assert (= 3 (length style-warnings
)))
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)
80 (declare (special x
)) y
)))))
81 (assert (= 1 ; (used to give 1 even under bug 112, still works after fix)
86 (declare (special x
)) y
)))))
88 ;;; another LET-related bug fixed by Alexey Dejneka at the same
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 ()
98 (assert (functionp fun
))
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
)
110 (funcall (symbol-function 'x-getter
))
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
119 (let ((fun (checked-compile `(lambda (n)
121 (declare (special *x
*))
122 (funcall (symbol-function 'x-getter
))
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*
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
)))
138 (when (typep i
'(and integer
(satisfies oddp
)))
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
)
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
)))
169 ;; on x86-64 the code for a literal symbol uses a slightly different path,
171 (assert (eq (handler-case xyzzy
*%state
172 (unbound-variable (c) (cell-error-name c
)))
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
)))
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
))
184 (destructuring-bind (form wrongp
) case
185 (multiple-value-bind (fun failure-p
)
186 (checked-compile form
:allow-failure wrongp
)
187 (assert (functionp fun
))
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)
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
))
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)
230 (make-array 1 :element-type
'(0)))
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))))
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.")
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.
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
))
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
325 (macrolet ((mext (x) `(cons :mext
,x
)))
326 (macrolet ((mint (y) `'(:mint
,(mext y
))))
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
))
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)))
377 (psetq x
(aref a
(incf 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
)
385 (let ((x (list 1 2)))
388 (assert (null result
))
389 (assert (typep error
'program-error
)))
391 ;;; COPY-SEQ should work on known-complex vectors:
393 (let ((v (make-array 0 :fill-pointer
0)))
394 (vector-push-extend 1 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
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)))
413 (array (loop (print (car a
))))))
416 (declare (ignore fun
))
418 (assert (= 1 (length warnings
)))))
420 ;;; Bug reported by Robert E. Brown sbcl-devel 2003-02-02: compiler
422 (with-test (:name
(:compiler-bug declare type loop
))
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
))
429 (loop for node
= (root-node tree
)
430 then
(if (funcall lessp key
(node-key node
))
434 do
(return (values nil nil nil
))
435 do
(when collect-path-p
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)
444 (let ((fn (constantly (progn (incf i
) 1))))
446 (assert (= (funcall fn
) 1))
448 (assert (= (funcall fn
) 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
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
)))
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
))
480 (assert (equal (multiple-value-list (the (values &rest integer
)
484 ;;; Bug relating to confused representation for the wild function
486 (assert (null (funcall (eval '(lambda () (multiple-value-list (values)))))))
488 ;;; &ENVIRONMENT parameter should be bound first (from Paul Dietz'
490 (assert (eql (macrolet ((foo () 1))
491 (macrolet ((%f
(&optional
(x (macroexpand '(foo) env
)) &environment env
)
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
)
503 (x &optional
(y nil x
))
504 (x &optional
(y nil y
)) ; TODO this case prints "caught ERROR: ..." but doesn't set failure-p
507 (&key
(y nil z
) (z nil w
))
508 (&whole x
&optional x
)))
509 (let ((style-warnings (nth-value
512 (macrolet ((foo ,ll nil
)
513 (bar (&environment env
)
514 `',(macro-function 'foo env
)))
516 :allow-style-warnings t
))))
517 (assert style-warnings
))))
519 ;; Uh, this test is semi-bogus - it's trying to test that you can't
520 ;; repeat, but it's now actually testing that &WHOLE has to appear
521 ;; first, per the formal spec.
522 (with-test (:name
(macrolet :lambda-list
&whole
:must-be-first
))
523 (assert-error (checked-compile
525 (macrolet ((foo (&environment x
&whole x
) nil
)
526 (bar (&environment env
)
527 `',(macro-function 'foo env
)))
530 (assert (typep (eval `(the arithmetic-error
531 ',(make-condition 'arithmetic-error
)))
534 (with-test (:name
(compile make-array
:dimensions nil
))
535 (checked-compile `(lambda ()
536 (make-array nil
:initial-element
11))))
538 (assert-error (funcall (eval #'open
) "assertoid.lisp"
539 :external-format
'#:nonsense
))
540 (assert-error (funcall (eval #'load
) "assertoid.lisp"
541 :external-format
'#:nonsense
))
543 (assert (= (the (values integer symbol
) (values 1 'foo
13)) 1))
545 (let ((f (compile nil
547 (declare (optimize (safety 3)))
548 (list (the fixnum
(the (real 0) (eval v
))))))))
549 (assert-error (funcall f
0.1) type-error
)
550 (assert-error (funcall f -
1) type-error
))
552 ;;; the implicit block does not enclose lambda list
553 (with-test (:name
(compile :implicit block
:does-not-enclose
:lambda-list
))
554 (let ((forms '((defmacro #1=#:foo
(&optional
(x (return-from #1#)))
555 (declare (ignore x
)))
556 #+nil
(macrolet ((#2=#:foo
(&optional
(x (return-from #2#))))))
557 (define-compiler-macro #3=#:foo
(&optional
(x (return-from #3#)))
558 (declare (ignore x
)))
559 (deftype #4=#:foo
(&optional
(x (return-from #4#)))
560 (declare (ignore x
)))
561 (define-setf-expander #5=#:foo
(&optional
(x (return-from #5#)))
562 (declare (ignore x
)))
563 (defsetf #6=#:foo
(&optional
(x (return-from #6#))) ()
564 (declare (ignore x
))))))
567 1 (checked-compile `(lambda () ,form
) :allow-failure t
))))))
569 (with-test (:name
(compile make-array svref
:derive-type
))
570 (multiple-value-bind (fun failurep warnings
)
571 (checked-compile `(lambda ()
572 (svref (make-array '(8 9) :adjustable t
) 1))
574 (declare (ignore fun
))
576 (assert (= 1 (length warnings
)))))
578 ;;; CHAR= did not check types of its arguments (reported by Adam Warner)
579 (macrolet ((define-char=-test
(function form
)
580 `(with-test (:name
(compile ,function
:argument-type-check
))
581 (assert-error (funcall (checked-compile ,form
) #\a #\b nil
)
583 (define-char=-test char
= `(lambda (x y z
) (char= x y z
)))
584 (define-char=-test char
/= `(lambda (x y z
)
585 (declare (optimize (speed 3) (safety 3)))
588 ;;; Compiler lost return type of MAPCAR and friends
589 (with-test (:name
(compile mapcar mapc maplist mapl
590 :return-type
:type-derivation
))
591 (dolist (fun '(mapcar mapc maplist mapl
))
592 (assert (= 1 (length (nth-value
595 (1+ (,fun
#'print x
)))
596 :allow-warnings t
))))))
598 (assert (= 1 (length (nth-value
601 (declare (notinline mapcar
))
602 (1+ (mapcar #'print
'(1 2 3))))
603 :allow-warnings t
))))))
605 ;;; bug found by Paul Dietz: (SETF AREF) for bit vectors with constant
606 ;;; index was effectless
607 (with-test (:name
(compile setf aref bit-vector
))
608 (let ((f (checked-compile `(lambda (a v
)
609 (declare (type simple-bit-vector a
) (type bit v
))
610 (declare (optimize (speed 3) (safety 0)))
613 (let ((y (make-array 2 :element-type
'bit
:initial-element
0)))
614 (assert (equal y
#*00))
616 (assert (equal y
#*10)))))
618 ;;; use of declared array types
619 (with-test (:name
(compile declare array type
:no sb-ext
:compiler-note
))
620 (dolist (form `((lambda (x)
621 (declare (type (simple-array (simple-string 3) (5)) x
)
625 (declare (type (simple-array (simple-array bit
(10)) (10)) x
)
627 (1+ (aref (aref x
0) 0)))))
628 (checked-compile form
:allow-notes nil
)))
631 (with-test (:name
(compile typep not member
))
632 (let ((f (checked-compile `(lambda (x) (typep x
'(not (member 0d0
)))))))
633 (assert (funcall f
1d0
))))
635 (with-test (:name
(compile double-float atan
))
636 (checked-compile `(lambda (x)
637 (declare (double-float x
))
641 ;;; bogus optimization of BIT-NOT
642 (multiple-value-bind (result x
)
643 (eval '(let ((x (eval #*1001)))
644 (declare (optimize (speed 2) (space 3))
645 (type (bit-vector) x
))
646 (values (bit-not x nil
) x
)))
647 (assert (equal x
#*1001))
648 (assert (equal result
#*0110)))
650 ;;; the VECTOR type in CONCATENATE/MERGE/MAKE-SEQUENCE means (VECTOR T).
651 (with-test (:name
(compile vector make-sequence sb-ext
:compiler-note
))
652 (let ((fun (checked-compile
654 (let ((x (make-sequence 'vector
10 :initial-element
'a
)))
658 (assert (equalp (funcall fun
) #(a a a a b a a a a a
)))))
660 ;;; this is not a check for a bug, but rather a test of compiler
662 (with-test (:name
(compile integer
:type-derivation
))
663 (dolist (type '((integer 0 *) ; upper bound
666 (real * (-10)) ; lower bound
668 (assert (= 1 (length (nth-value
671 (declare (optimize (speed 3) (compilation-speed 0)))
672 (loop for i from
1 to
(the (integer -
17 10) n
) by
2
673 collect
(when (> (random 10) 5)
674 (the ,type
(- i
11)))))
675 :allow-warnings t
)))))))
679 ;;; We suppose that INTEGER arithmetic cannot be efficient, and the
680 ;;; compiler has an optimized VOP for +; so this code should cause an
682 (with-test (:name
(compile integer
+ sb-ext
:compiler-note
:bug-278b
))
683 (assert (= 1 (length (nth-value
686 (declare (optimize speed
))
687 (declare (type integer i
))
690 ;;; bug 277: IGNORE/IGNORABLE declarations should be acceptable for
692 (with-test (:name
(compile symbol-macrolet ignore ignorable
:bug-277
))
693 (checked-compile `(lambda (u v
)
694 (symbol-macrolet ((x u
)
700 ;;; bug reported by Paul Dietz: wrong optimizer for (EXPT ... 0)
701 (loop for
(x type
) in
704 (-14/3 (rational -
8 11))
713 (#c
(-3 4) (complex fixnum
))
714 (#c
(-3 4) (complex rational
))
715 (#c
(-3/7 4) (complex rational
))
716 (#c
(2s0 3s0
) (complex short-float
))
717 (#c
(2f0 3f0
) (complex single-float
))
718 (#c
(2d0 3d0
) (complex double-float
))
719 (#c
(2l0 3l0) (complex long-float
))
720 (#c
(2d0 3s0
) (complex float
))
721 (#c
(2 3f0
) (complex real
))
722 (#c
(2 3d0
) (complex real
))
723 (#c
(-3/7 4) (complex real
))
726 do
(dolist (zero '(0 0s0
0f0
0d0
0l0))
727 (dolist (real-zero (list zero
(- zero
)))
728 (let* ((src `(lambda (x) (expt (the ,type x
) ,real-zero
)))
729 (fun (compile nil src
))
730 (result (1+ (funcall (eval #'*) x real-zero
))))
731 (assert (eql result
(funcall fun x
)))))))
733 ;;; (SIGNED-BYTE 1) [ returned from the logxor derive-type optimizer ]
734 ;;; wasn't recognized as a good type specifier.
735 (let ((fun (lambda (x y
)
736 (declare (type (integer -
1 0) x y
) (optimize speed
))
738 (assert (= (funcall fun
0 0) 0))
739 (assert (= (funcall fun
0 -
1) -
1))
740 (assert (= (funcall fun -
1 -
1) 0)))
742 ;;; from PFD's torture test, triggering a bug in our effective address
744 (with-test (:name
(compile declare type logandc1 logandc2
))
745 (checked-compile `(lambda (a b
)
746 (declare (type (integer 8 22337) b
))
749 (* (logandc1 (max -
29303 b
) 4) b
)
750 (abs (logorc1 (+ (logandc1 -
11 b
) 2607688420) -
31153924)))
751 (logeqv (max a
0) b
)))))
753 ;;; Alpha floating point modes weren't being reset after an exception,
754 ;;; leading to an exception on the second compile, below.
755 (with-test (:name
(compile :floating-point-mode
))
756 (let ((form `(lambda (x y
) (declare (type (double-float 0.0d0
) x y
)) (/ x y
))))
757 (checked-compile form
)
758 (handler-case (/ 1.0 0.0)
759 ;; provoke an exception
760 (arithmetic-error ()))
761 (checked-compile form
)))
763 ;;; bug reported by Paul Dietz: component last block does not have
765 (with-test (:name
(compile block return-from
))
766 (checked-compile `(lambda ()
767 (declare (notinline + logand
)
768 (optimize (speed 0)))
772 (return-from b5 -
220)))
774 (+ 359749 35728422))))
777 (with-test (:name
:ansi-misc
.293a
)
782 (declare (optimize (speed 2) (space 3) (safety 1)
783 (debug 2) (compilation-speed 2)))
785 (multiple-value-prog1
790 (complex (cl::handler-bind nil -
254932942) 0))))))))
794 (with-test (:name
:ansi-misc
.293d
)
798 (declare (optimize (debug 3) (safety 0) (space 2)
799 (compilation-speed 2) (speed 2)))
801 (multiple-value-prog1
804 (return-from b4
(catch 'ct2
(progn (tagbody) 0)))))))))
807 (with-test (:name
:ansi-misc
.618)
811 (declare (optimize (space 0) (compilation-speed 2) (debug 0)
812 (speed 3) (safety 0)))
815 (multiple-value-prog1 0
816 (apply (constantly 0)
818 (catch 'ct2
(return-from b1
0))
823 ;;; bug 294 reported by Paul Dietz: miscompilation of REM and MOD
824 (with-test (:name
(compile rem
:bug-294
))
825 (assert (= (funcall (checked-compile
827 (declare (optimize (speed 3))
828 (type (integer 2 152044363) b
))
829 (rem b
(min -
16 0))))
833 (with-test (:name
(compile mod
:bug-294
))
834 (assert (= (funcall (checked-compile
836 (declare (optimize (speed 3))
837 (type (integer 23062188 149459656) c
))
842 ;;; bug reported by Paul Dietz: block splitting inside FLUSH-DEAD-CODE
843 (with-test (:name
(compile logeqv rem
:dead-code
:block-splitting
))
844 (checked-compile `(lambda (a b c
)
846 (logeqv (rem c -
6758)
847 (rem b
(max 44 (return-from b6 a
))))))))
849 (with-test (:name
(compile block flet
:dead-code
:block-splitting
))
850 (checked-compile `(lambda ()
852 (flet ((foo (x y
) (if (> x y
) (print x
) (print y
))))
855 (foo (return 14) 2))))
856 :allow-style-warnings t
))
858 ;;; bug in Alpha backend: not enough sanity checking of arguments to
860 (assert (= (funcall (compile nil
867 ;;; bug found by WHN and pfdietz: compiler failure while referencing
868 ;;; an entry point inside a deleted lambda
869 (with-test (:name
(compile :reference-entry-point-in-deleted lambda
))
876 (flet ((truly (fn bbd
)
880 (multiple-value-prog1
897 (wum #'bbfn
"hc3" (list)))
899 :allow-failure t
:allow-style-warnings t
))
901 (with-test (:name
(compile flet unwind-protect
:dead-code
))
902 (checked-compile `(lambda () (flet ((%f
() (unwind-protect nil
))) nil
))))
904 ;;; the strength reduction of constant multiplication used (before
905 ;;; sbcl-0.8.4.x) to lie to the compiler. This meant that, under
906 ;;; certain circumstances, the compiler would derive that a perfectly
907 ;;; reasonable multiplication never returned, causing chaos. Fixed by
908 ;;; explicitly doing modular arithmetic, and relying on the backends
913 (declare (type (integer 178956970 178956970) x
)
919 ;;; bug in modular arithmetic and type specifiers
920 (assert (= (funcall (compile nil
'(lambda (x) (logand x x
0)))
924 ;;; MISC.99 from Paul Dietz' random tester: FAST-ASH-MOD32-C VOP
925 ;;; produced wrong result for shift >=32 on X86
926 (assert (= 0 (funcall
929 (declare (type (integer 4303063 101130078) a
))
930 (mask-field (byte 18 2) (ash a
77))))
932 ;;; rewrite the test case to get the unsigned-byte 32/64
933 ;;; implementation even after implementing some modular arithmetic
934 ;;; with signed-byte 30:
935 (assert (= 0 (funcall
938 (declare (type (integer 4303063 101130078) a
))
939 (mask-field (byte 30 2) (ash a
77))))
941 (assert (= 0 (funcall
944 (declare (type (integer 4303063 101130078) a
))
945 (mask-field (byte 64 2) (ash a
77))))
947 ;;; and a similar test case for the signed masking extension (not the
948 ;;; final interface, so change the call when necessary):
949 (assert (= 0 (funcall
952 (declare (type (integer 4303063 101130078) a
))
953 (sb-c::mask-signed-field
30 (ash a
77))))
955 (assert (= 0 (funcall
958 (declare (type (integer 4303063 101130078) a
))
959 (sb-c::mask-signed-field
61 (ash a
77))))
962 ;;; MISC.101 and MISC.103: FLUSH-DEST did not mark the USE's block for
963 ;;; type check regeneration
964 (assert (eql (funcall
965 (compile nil
'(lambda (a c
)
966 (declare (type (integer 185501219873 303014665162) a
))
967 (declare (type (integer -
160758 255724) c
))
968 (declare (optimize (speed 3)))
970 (- -
554046873252388011622614991634432
972 (unwind-protect 2791485))))
973 (max (ignore-errors a
)
974 (let ((v6 (- v8
(restart-case 980))))
978 (assert (eql (funcall
979 (compile nil
'(lambda (a b
)
987 (load-time-value -
6876935))))
988 (if (logbitp 1 a
) b
(setq a -
1522022182249))))))))
989 -
1802767029877 -
12374959963)
992 ;;; various MISC.*, related to NODEs/LVARs with derived type NIL
993 (assert (eql (funcall (compile nil
'(lambda (c)
994 (declare (type (integer -
3924 1001809828) c
))
995 (declare (optimize (speed 3)))
996 (min 47 (if (ldb-test (byte 2 14) c
)
998 (ignore-errors -
732893970)))))
1001 (assert (eql (funcall
1002 (compile nil
'(lambda (b)
1003 (declare (type (integer -
1598566306 2941) b
))
1004 (declare (optimize (speed 3)))
1005 (max -
148949 (ignore-errors b
))))
1008 (assert (eql (funcall
1009 (compile nil
'(lambda (b c
)
1010 (declare (type (integer -
4 -
3) c
))
1012 (flet ((%f1
(f1-1 f1-2 f1-3
)
1013 (if (logbitp 0 (return-from b7
1014 (- -
815145138 f1-2
)))
1015 (return-from b7 -
2611670)
1017 (let ((v2 (%f1 -
2464 (%f1 -
1146 c c
) -
2)))
1021 (assert (eql (funcall
1024 (declare (type (integer -
29742055786 23602182204) b
))
1025 (declare (type (integer -
7409 -
2075) c
))
1026 (declare (optimize (speed 3)))
1030 (ignore-errors (return-from b6
1031 (if (= c
8) b
82674))))))
1035 (assert (equal (multiple-value-list
1037 (compile nil
'(lambda (a)
1038 (declare (type (integer -
944 -
472) a
))
1039 (declare (optimize (speed 3)))
1043 (if (= 55957 a
) -
117 (ignore-errors
1044 (return-from b3 a
))))))))
1049 (assert (zerop (funcall
1052 (declare (type (integer 79828 2625480458) a
))
1053 (declare (type (integer -
4363283 8171697) b
))
1054 (declare (type (integer -
301 0) c
))
1055 (if (equal 6392154 (logxor a b
))
1059 (logior (logandc2 c v5
)
1060 (common-lisp:handler-case
1061 (ash a
(min 36 22477)))))))))
1064 ;;; MISC.152, 153: deleted code and iteration var type inference
1065 (assert (eql (funcall
1069 (let ((v1 (let ((v8 (unwind-protect 9365)))
1073 (labels ((%f11
(f11-1) f11-1
))
1077 (labels ((%f6
(f6-1 f6-2 f6-3
) v1
))
1078 (dpb (unwind-protect a
)
1080 (labels ((%f4
() 27322826))
1081 (%f6 -
2 -
108626545 (%f4
))))))))))))
1085 (assert (eql (funcall
1090 ((-96879 -
1035 -
57680 -
106404 -
94516 -
125088)
1091 (unwind-protect 90309179))
1092 ((-20811 -
86901 -
9368 -
98520 -
71594)
1093 (let ((v9 (unwind-protect 136707)))
1096 (let ((v4 (return-from b3 v9
)))
1097 (- (ignore-errors (return-from b3 v4
))))))))
1105 (assert (eql (funcall
1116 &optional
(f17-4 185155520) (f17-5 c
)
1119 (%f17 -
1046 a
1115306 (%f17 b -
146330 422) -
337817)))
1120 (f15-5 a
) (f15-6 -
40))
1121 (return-from b3 -
16)))
1122 (multiple-value-call #'%f15
(values -
519354 a
121 c -
1905))))))
1127 (assert (eql (funcall
1131 (declare (notinline list apply
))
1132 (declare (optimize (safety 3)))
1133 (declare (optimize (speed 0)))
1134 (declare (optimize (debug 0)))
1135 (labels ((%f12
(f12-1 f12-2
)
1136 (labels ((%f2
(f2-1 f2-2
)
1143 (return-from %f12 b
)))
1146 (%f18
(%f18
150 -
64 f12-1
)
1153 &optional
(f7-3 (%f6
)))
1156 (%f2 b -
36582571))))
1157 (apply #'%f12
(list 774 -
4413)))))
1162 (assert (eql (funcall
1166 (declare (notinline values
))
1167 (declare (optimize (safety 3)))
1168 (declare (optimize (speed 0)))
1169 (declare (optimize (debug 0)))
1172 &optional
(f11-3 c
) (f11-4 7947114)
1174 (flet ((%f3
(f3-1 &optional
(f3-2 b
) (f3-3 5529))
1176 (multiple-value-call #'%f3
1177 (values (%f3 -
30637724 b
) c
)))))
1179 (if (and nil
(%f11 a a
))
1180 (if (%f11 a
421778 4030 1)
1186 (%f11 c a c -
4 214720)
1198 ;;; MISC.177, 182: IR2 copy propagation missed a hidden write to a
1199 ;;; local lambda argument
1205 (declare (type (integer 804561 7640697) a
))
1206 (declare (type (integer -
1 10441401) b
))
1207 (declare (type (integer -
864634669 55189745) c
))
1208 (declare (ignorable a b c
))
1209 (declare (optimize (speed 3)))
1210 (declare (optimize (safety 1)))
1211 (declare (optimize (debug 1)))
1214 (labels ((%f4
() (round 200048 (max 99 c
))))
1217 (labels ((%f3
(f3-1) -
162967612))
1218 (%f3
(let* ((v8 (%f4
)))
1219 (setq f11-1
(%f4
)))))))))
1220 (%f11 -
120429363 (%f11
62362 b
)))))
1221 6714367 9645616 -
637681868)
1224 ;;; Bug reported by Paul F. Dietz caused by derive type loss in VALUE
1226 (assert (equal (multiple-value-list
1228 (compile nil
'(lambda ()
1229 (declare (optimize (speed 1) (space 0) (safety 3) (debug 3) (compilation-speed 1)))
1232 (flet ((%f16
() 0)) (%f16
))))))))
1241 (declare (type (integer 867934833 3293695878) a
))
1242 (declare (type (integer -
82111 1776797) b
))
1243 (declare (type (integer -
1432413516 54121964) c
))
1244 (declare (optimize (speed 3)))
1245 (declare (optimize (safety 1)))
1246 (declare (optimize (debug 1)))
1248 (flet ((%f15
(f15-1 &optional
(f15-2 c
))
1249 (labels ((%f1
(f1-1 f1-2
) 0))
1252 (multiple-value-call #'%f15
1253 (values (%f15 c
0) (%f15
0)))))
1255 (flet ((%f8
(f8-1 &optional
(f8-2 (%f4
)) (f8-3 0))
1259 3040851270 1664281 -
1340106197)))
1267 (declare (notinline <=))
1268 (declare (optimize (speed 2) (space 3) (safety 0)
1269 (debug 1) (compilation-speed 3)))
1270 (if (if (<= 0) nil nil
)
1271 (labels ((%f9
(f9-1 f9-2 f9-3
)
1273 (dotimes (iv4 5 a
) (%f9
0 0 b
)))
1277 ;;; MISC.259-264 (aka "CSR screwed up implementing *-MOD32")
1283 (declare (type (integer 177547470 226026978) a
))
1284 (declare (optimize (speed 3) (space 0) (safety 0) (debug 0)
1285 (compilation-speed 1)))
1286 (logand a
(* a
438810))))
1291 ;;;; Bugs in stack analysis
1292 ;;; bug 299 (reported by PFD)
1298 (declare (optimize (debug 1)))
1299 (multiple-value-call #'list
1300 (if (eval t
) (eval '(values :a
:b
:c
)) nil
)
1301 (catch 'foo
(throw 'foo
(values :x
:y
)))))))
1303 ;;; bug 298 (= MISC.183)
1304 (assert (zerop (funcall
1308 (declare (type (integer -
368154 377964) a
))
1309 (declare (type (integer 5044 14959) b
))
1310 (declare (type (integer -
184859815 -
8066427) c
))
1311 (declare (ignorable a b c
))
1312 (declare (optimize (speed 3)))
1313 (declare (optimize (safety 1)))
1314 (declare (optimize (debug 1)))
1316 (flet ((%f3
(f3-1 f3-2 f3-3
) 0))
1317 (apply #'%f3
0 (catch 'foo
(return-from b7
(%f3
0 b c
))) c nil
)))))
1319 (assert (equal (eval '(let () (apply #'list
1 (list (catch 'a
(throw 'a
(block b
2)))))))
1325 (multiple-value-call #'list
1329 (multiple-value-call #'list
1335 (return-from quux
1)
1336 (throw 'baz
2))))))))))))))
1337 (assert (equal (funcall f t
) '(:b
1)))
1338 (assert (equal (funcall f nil
) '(:a
2))))
1346 (declare (type (integer 5 155656586618) a
))
1347 (declare (type (integer -
15492 196529) b
))
1348 (declare (type (integer 7 10) c
))
1349 (declare (optimize (speed 3)))
1350 (declare (optimize (safety 1)))
1351 (declare (optimize (debug 1)))
1354 &optional
(f3-4 a
) (f3-5 0)
1356 (labels ((%f10
(f10-1 f10-2 f10-3
)
1361 (- (if (equal a b
) b
(%f10 c a
0))
1362 (catch 'ct2
(throw 'ct2 c
)))
1365 (%f3
(%f3
(%f3 b
0 0 0) a
0) a b b b c
)))) 5 0 7)
1370 '(let* ((form '(labels ((%f3
(f3-1 f3-2
) f3-1
))
1371 (apply #'%f3 b
(catch 'ct8
(throw 'ct8
(logeqv (%f3 c
0)))) nil
)))
1374 (declare (type (integer -
2 19) b
)
1375 (type (integer -
1520 218978) c
)
1376 (optimize (speed 3) (safety 1) (debug 1)))
1379 (declare (notinline logeqv apply
)
1380 (optimize (safety 3) (speed 0) (debug 0)))
1382 (cf1 (compile nil fn1
))
1383 (cf2 (compile nil fn2
))
1384 (result1 (multiple-value-list (funcall cf1
2 18886)))
1385 (result2 (multiple-value-list (funcall cf2
2 18886))))
1386 (if (equal result1 result2
)
1388 (values result1 result2
))))
1398 (optimize (speed 3) (space 3) (safety 1)
1399 (debug 2) (compilation-speed 0)))
1400 (apply (constantly 0) (catch 'ct2
0) 0 (catch 'ct2
0) nil
))))))
1403 (assert (zerop (funcall
1407 (declare (optimize (speed 2) (space 0) (safety 3) (debug 1)
1408 (compilation-speed 2)))
1409 (apply (constantly 0)
1413 (apply (constantly 0)
1432 (declare (optimize (speed 1) (space 0) (safety 0) (debug 0)))
1433 (multiple-value-prog1
1434 (the integer
(catch 'ct8
(catch 'ct7
15867134)))
1435 (catch 'ct1
(throw 'ct1
0))))))
1438 ;;; misc.361: replacing CAST with (m-v-call #'%compile-time-type-error)
1439 ;;; could transform known-values LVAR to UVL
1440 (assert (zerop (funcall
1444 (declare (notinline boole values denominator list
))
1450 (compilation-speed 2)))
1455 (let ((v9 (ignore-errors (throw 'ct6
0))))
1457 (progv nil nil
(values (boole boole-and
0 v9
)))))))))
1460 ;;; non-continuous dead UVL blocks
1461 (defun non-continuous-stack-test (x)
1462 (multiple-value-call #'list
1463 (eval '(values 11 12))
1464 (eval '(values 13 14))
1466 (return-from non-continuous-stack-test
1467 (multiple-value-call #'list
1468 (eval '(values :b1
:b2
))
1469 (eval '(values :b3
:b4
))
1472 (multiple-value-call (eval #'values
)
1473 (eval '(values 1 2))
1474 (eval '(values 3 4))
1477 (multiple-value-call (eval #'values
)
1478 (eval '(values :a1
:a2
))
1479 (eval '(values :a3
:a4
))
1482 (multiple-value-call (eval #'values
)
1483 (eval '(values 5 6))
1484 (eval '(values 7 8))
1487 (return-from int
:int
))))))))))))))))
1488 (assert (equal (non-continuous-stack-test t
) '(11 12 13 14 1 2 3 4 5 6 7 8 :ext
)))
1489 (assert (equal (non-continuous-stack-test nil
) '(:b1
:b2
:b3
:b4
:a1
:a2
:a3
:a4
:int
)))
1491 ;;; MISC.362: environment of UNWIND-PROTECTor is different from that
1493 (assert (equal (multiple-value-list (funcall
1497 (declare (optimize (speed 3) (space 3) (safety 2)
1498 (debug 2) (compilation-speed 3)))
1501 (labels ((%f15
(f15-1 f15-2 f15-3
)
1502 (rational (throw 'ct5
0))))
1508 (progv '(*s2
* *s5
*) (list 0 (%f15
0 g
0)) b
)
1512 (common-lisp:handler-case
0)))))
1524 (declare (notinline funcall min coerce
))
1530 (compilation-speed 1)))
1531 (flet ((%f12
(f12-1)
1534 (if f12-1
(multiple-value-prog1
1535 b
(return-from %f12
0))
1538 (funcall #'%f12
0))))
1541 ;;; Discussion of a CMUCL PCL bug on Sparc with Raymond Toy revealed a
1542 ;;; potential problem: optimizers and type derivers for MAX and MIN
1543 ;;; were not consistent in treating EQUALP, but not EQL, arguments.
1544 (dolist (f '(min max
))
1545 (loop for complex-arg-args in
'((1d0 2d0
) (0d0 1d0
))
1546 for complex-arg
= `(if x
,@complex-arg-args
)
1548 (loop for args in
`((1 ,complex-arg
)
1550 for form
= `(,f
,@args
)
1551 for f1
= (compile nil
`(lambda (x) ,form
))
1552 and f2
= (compile nil
`(lambda (x) (declare (notinline min max
))
1555 (dolist (x '(nil t
))
1556 (assert (eql (funcall f1 x
) (funcall f2 x
)))))))
1559 (handler-case (compile nil
'(lambda (x)
1560 (declare (optimize (speed 3) (safety 0)))
1561 (the double-float
(sqrt (the double-float x
)))))
1562 (sb-ext:compiler-note
(c)
1563 ;; Ignore the note for the float -> pointer conversion of the
1565 (unless (string= (car (last (sb-c::simple-condition-format-arguments c
)))
1567 (error "Compiler does not trust result type assertion."))))
1569 (let ((f (compile nil
'(lambda (x)
1570 (declare (optimize speed
(safety 0)))
1573 (multiple-value-prog1
1574 (sqrt (the double-float x
))
1576 (return :minus
)))))))))
1577 (assert (eql (funcall f -
1d0
) :minus
))
1578 (assert (eql (funcall f
4d0
) 2d0
)))
1580 ;;; bug 304: SBCL produced something similar to (/ (ASH x 4) 8)
1582 (compile nil
'(lambda (a i
)
1584 (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)
1585 (inhibit-warnings 0)))
1586 (declare (type (alien (* (unsigned 8))) a
)
1587 (type (unsigned-byte 32) i
))
1590 (unless (search "%ASH/RIGHT" (first (simple-condition-format-arguments c
)))
1591 (error "The code is not optimized."))))
1594 (compile nil
'(lambda (x)
1595 (declare (type (integer -
100 100) x
))
1596 (declare (optimize speed
))
1597 (declare (notinline identity
))
1599 (compiler-note () (error "IDENTITY derive-type not applied.")))
1601 (assert (null (funcall (compile nil
'(lambda (x) (funcall #'cddr x
))) nil
)))
1603 ;;; MISC.293 = easy variant of bug 303: repeated write to the same
1604 ;;; LVAR; here the first write may be cleared before the second is
1612 (declare (notinline complex
))
1613 (declare (optimize (speed 1) (space 0) (safety 1)
1614 (debug 3) (compilation-speed 3)))
1615 (flet ((%f
() (multiple-value-prog1 0 (return-from %f
0))))
1616 (complex (%f
) 0)))))))
1618 ;;; MISC.110A: CAST optimizer forgot to flush LVAR derived type
1619 (assert (zerop (funcall
1623 (declare (type (integer -
1294746569 1640996137) a
))
1624 (declare (type (integer -
807801310 3) c
))
1625 (declare (optimize (speed 3) (space 3) (safety 0) (debug 0) (compilation-speed 3)))
1632 (progn (if (ldb-test (byte 0 0) (rational (throw 'ct7
0))) 0 0) 0))))
1634 391833530 -
32785211)))
1636 ;;; efficiency notes for ordinary code
1637 (macrolet ((frob (arglist &body body
)
1640 (compile nil
'(lambda ,arglist
,@body
))
1641 (sb-ext:compiler-note
(e)
1642 (error "bad compiler note for ~S:~% ~A" ',body e
)))
1644 (handler-bind ((compiler-note
1646 (setq gotit t
) (muffle-warning c
))))
1647 (compile nil
'(lambda ,arglist
(declare (optimize speed
))
1650 (error "missing compiler note for ~S" ',body
))))))
1651 (frob (x) (funcall x
))
1652 (frob (x y
) (find x y
))
1653 (frob (x y
) (find-if x y
))
1654 (frob (x y
) (find-if-not x y
))
1655 (frob (x y
) (position x y
))
1656 (frob (x y
) (position-if x y
))
1657 (frob (x y
) (position-if-not x y
))
1658 (frob (x) (aref x
0)))
1660 (macrolet ((frob (style-warn-p form
)
1661 (unless (eq (car form
) 'lambda
)
1662 (setq form
`(lambda () ,form
)))
1665 (handler-bind ((style-warning
1667 (setq gotit t
) (muffle-warning c
))))
1668 (compile nil
',form
))
1670 (error "missing style-warning for ~S" ',form
)))
1672 (compile nil
',form
)
1674 (error "bad style-warning for ~S: ~A" ',form e
))))))
1675 (frob t
(lambda (x &optional y
&key z
) (list x y z
)))
1676 (frob nil
(lambda (x &optional y z
) (list x y z
)))
1677 (frob nil
(lambda (x &key y z
) (list x y z
)))
1678 (frob t
(defgeneric #:foo
(x &optional y
&key z
)))
1679 (frob nil
(defgeneric #:foo
(x &optional y z
)))
1680 (frob nil
(defgeneric #:foo
(x &key y z
)))
1681 (frob t
(defun #:foo
(x) (flet ((foo (x &optional y
&key z
) (list x y z
))) (foo x x
:z x
)))))
1683 ;;; this was a bug in the LOGXOR type deriver. The top form gave a
1684 ;;; note, because the system failed to derive the fact that the return
1685 ;;; from LOGXOR was small and negative, though the bottom one worked.
1686 (handler-bind ((sb-ext:compiler-note
#'error
))
1687 (compile nil
'(lambda ()
1688 (declare (optimize speed
(safety 0)))
1690 (declare (type (integer 3 6) x
)
1691 (type (integer -
6 -
3) y
))
1692 (+ (logxor x y
) most-positive-fixnum
)))))
1693 (handler-bind ((sb-ext:compiler-note
#'error
))
1694 (compile nil
'(lambda ()
1695 (declare (optimize speed
(safety 0)))
1697 (declare (type (integer 3 6) y
)
1698 (type (integer -
6 -
3) x
))
1699 (+ (logxor x y
) most-positive-fixnum
)))))
1701 ;;; check that modular ash gives the right answer, to protect against
1702 ;;; possible misunderstandings about the hardware shift instruction.
1703 (assert (zerop (funcall
1704 (compile nil
'(lambda (x y
)
1705 (declare (optimize speed
)
1706 (type (unsigned-byte 32) x y
))
1707 (logand #xffffffff
(ash x y
))))
1710 ;;; code instrumenting problems
1713 (declare (optimize (debug 3)))
1714 (list (the integer
(if nil
14 t
)))))
1718 (DECLARE (NOTINLINE LOGORC1 BYTE MASK-FIELD
))
1724 (COMPILATION-SPEED 0)))
1725 (MASK-FIELD (BYTE 7 26)
1727 (TAGBODY (THE INTEGER
(CATCH 'CT4
(LOGORC1 C -
15950))) 1)
1731 '(lambda (buffer i end
)
1732 (declare (optimize (debug 3)))
1733 (loop (when (not (eql 0 end
)) (return)))
1734 (let ((s (make-string end
)))
1735 (setf (schar s i
) (schar buffer i
))
1738 ;;; check that constant string prefix and suffix don't cause the
1739 ;;; compiler to emit code deletion notes.
1740 (handler-bind ((sb-ext:code-deletion-note
#'error
))
1741 (compile nil
'(lambda (s x
)
1742 (pprint-logical-block (s x
:prefix
"(")
1744 (compile nil
'(lambda (s x
)
1745 (pprint-logical-block (s x
:per-line-prefix
";")
1747 (compile nil
'(lambda (s x
)
1748 (pprint-logical-block (s x
:suffix
">")
1751 ;;; MISC.427: loop analysis requires complete DFO structure
1752 (assert (eql 17 (funcall
1756 (declare (notinline list reduce logior
))
1757 (declare (optimize (safety 2) (compilation-speed 1)
1758 (speed 3) (space 2) (debug 2)))
1760 (let* ((v5 (reduce #'+ (list 0 a
))))
1761 (declare (dynamic-extent v5
))
1766 (assert (zerop (funcall
1770 (declare (type (integer -
8431780939320 1571817471932) a
))
1771 (declare (type (integer -
4085 0) b
))
1772 (declare (ignorable a b
))
1775 (compilation-speed 0)
1776 #+sbcl
(sb-c:insert-step-conditions
0)
1783 (elt '(1954479092053)
1787 (lognand iv1
(ash iv1
(min 53 iv1
)))
1790 -
7639589303599 -
1368)))
1795 (declare (type (integer) a
))
1796 (declare (type (integer) b
))
1797 (declare (ignorable a b
))
1798 (declare (optimize (space 2) (compilation-speed 0)
1799 (debug 0) (safety 0) (speed 3)))
1801 (when (< iv1
2) (print 'x
)) ;; request for second constraint propagation pass
1802 (print (if (< iv1 iv1
)
1803 (logand (ash iv1 iv1
) 1)
1806 ;;; MISC.435: lambda var substitution in a deleted code.
1807 (assert (zerop (funcall
1811 (declare (notinline aref logandc2 gcd make-array
))
1813 (optimize (space 0) (safety 0) (compilation-speed 3)
1814 (speed 3) (debug 1)))
1817 (let* ((v2 (make-array nil
:initial-element
(catch 'ct1
(go tag2
)))))
1818 (declare (dynamic-extent v2
))
1819 (gcd (go tag2
) (logandc2 (catch 'ct2 c
) (aref v2
))))
1822 3021871717588 -
866608 -
2 -
17194)))
1824 ;;; MISC.436, 438: lost reoptimization
1825 (assert (zerop (funcall
1829 (declare (type (integer -
2917822 2783884) a
))
1830 (declare (type (integer 0 160159) b
))
1831 (declare (ignorable a b
))
1833 (optimize (compilation-speed 1)
1837 ; #+sbcl (sb-c:insert-step-conditions 0)
1851 '(-10197561 486 430631291
1857 (assert (zerop (funcall
1861 (declare (type (integer 0 1696) a
))
1862 ; (declare (ignorable a))
1863 (declare (optimize (space 2) (debug 0) (safety 1)
1864 (compilation-speed 0) (speed 1)))
1865 (if (logbitp 0 (ash (1- a
) (min 11 a
))) 0 0)))
1872 (declare (type (simple-array function
(2)) s
) (type ei ei
))
1873 (funcall (aref s ei
) x y
))))
1875 ;;; MISC.320: ir1-transform can create an intercomponent reference to
1877 (assert (eql 102 (funcall
1881 (declare (optimize (speed 3) (space 0) (safety 2)
1882 (debug 2) (compilation-speed 0)))
1885 (flet ((%f12
() (rem 0 -
43)))
1886 (multiple-value-call #'%f12
(values))))))))))
1888 ;;; MISC.437: lost reoptimization after FLUSH-DEST
1889 (assert (zerop (funcall
1892 '(lambda (a b c d e
)
1893 (declare (notinline values complex eql
))
1895 (optimize (compilation-speed 3)
1902 &optional
(f10-4 (ignore-errors 0)) (f10-5 0)
1903 &key
&allow-other-keys
)
1904 (if (or (eql 0 0) t
) 0 (if f10-1
0 0))))
1905 (complex (multiple-value-call #'%f10
(values a c b
0 0)) 0))))
1906 80043 74953652306 33658947 -
63099937105 -
27842393)))
1908 ;;; bug #351 -- program-error for malformed LET and LET*, including those
1909 ;;; resulting from SETF of LET.
1910 (with-test (:name
:bug-351
)
1911 (dolist (fun (list (compile nil
'(lambda (x) (let :bogus-let
:oops
)))
1912 (compile nil
'(lambda (x) (let* :bogus-let
* :oops
)))
1913 (compile nil
'(lambda (x) (push x
(let ((y 0)) y
))))))
1914 (assert (functionp fun
))
1915 (multiple-value-bind (res err
) (ignore-errors (funcall fun t
))
1916 (princ err
) (terpri)
1918 (assert (typep err
'program-error
)))))
1920 (let ((fun (compile nil
'(lambda (x) (random (if x
10 20))))))
1921 (dotimes (i 100 (error "bad RANDOM distribution"))
1922 (when (> (funcall fun nil
) 9)
1925 (when (> (funcall fun t
) 9)
1926 (error "bad RANDOM event"))))
1928 ;;; 0.8.17.28-sma.1 lost derived type information.
1929 (with-test (:name
:0.8.17.28-sma
.1 :fails-on
:sparc
)
1930 (handler-bind ((sb-ext:compiler-note
(lambda (c) (error "~A" c
))))
1933 (declare (optimize (speed 3) (safety 0)))
1934 (declare (type (integer 0 80) x
)
1935 (type (integer 0 11) y
)
1936 (type (simple-array (unsigned-byte 32) (*)) v
))
1937 (setf (aref v
0) (* (* x
#.
(floor (ash 1 32) (* 11 80))) y
))
1940 ;;; Bug reported by Robert J. Macomber: instrumenting of more-entry
1941 ;;; prevented open coding of %LISTIFY-REST-ARGS.
1942 (let ((f (compile nil
'(lambda ()
1943 (declare (optimize (debug 3)))
1944 (with-simple-restart (blah "blah") (error "blah"))))))
1945 (handler-bind ((error (lambda (c) (invoke-restart 'blah
))))
1946 (assert (equal (multiple-value-list (funcall f
)) '(nil t
)))))
1948 ;;; Bug reported by Timmy Douglas: overflow in bit vector setter with
1949 ;;; constant index and value.
1950 (loop for n-bits
= 1 then
(* n-bits
2)
1951 for type
= `(unsigned-byte ,n-bits
)
1952 and v-max
= (1- (ash 1 n-bits
))
1953 while
(<= n-bits sb-vm
:n-word-bits
)
1955 (let* ((n (* 2 (1+ (- sb-vm
::n-word-bits n-bits
))))
1956 (array1 (make-array n
:element-type type
))
1957 (array2 (make-array n
:element-type type
)))
1959 (dolist (v (list 0 v-max
))
1960 (let ((f (compile nil
`(lambda (a)
1961 (declare (type (simple-array ,type
(,n
)) a
))
1962 (setf (aref a
,i
) ,v
)))))
1963 (fill array1
(- v-max v
))
1964 (fill array2
(- v-max v
))
1966 (setf (aref array2 i
) v
)
1967 (assert (every #'= array1 array2
)))))))
1969 (let ((fn (compile nil
'(lambda (x)
1970 (declare (type bit x
))
1971 (declare (optimize speed
))
1972 (let ((b (make-array 64 :element-type
'bit
1973 :initial-element
0)))
1975 (assert (= (funcall fn
0) 64))
1976 (assert (= (funcall fn
1) 0)))
1978 (let ((fn (compile nil
'(lambda (x y
)
1979 (declare (type simple-bit-vector x y
))
1980 (declare (optimize speed
))
1984 (make-array 64 :element-type
'bit
:initial-element
0)
1985 (make-array 64 :element-type
'bit
:initial-element
0)))
1989 (make-array 64 :element-type
'bit
:initial-element
0)
1990 (let ((b (make-array 64 :element-type
'bit
:initial-element
0)))
1991 (setf (sbit b
63) 1)
1994 ;;; MISC.535: compiler failure
1995 (let ((c0 #c
(4196.088977268509d0 -
15943.3603515625d0
)))
1996 (assert (not (funcall
2000 (declare (optimize speed
(safety 1))
2003 (eql (the (complex double-float
) p1
) p2
)))
2004 c0
#c
(12 612/979)))))
2006 ;;; reported by Lutz Euler: we shouldn't signal a compiler note for
2007 ;;; simple-bit-vector functions.
2008 (with-test (:name
(:simple-bit-vector
:count
:should-not-compiler-note
))
2009 (handler-bind ((sb-ext:compiler-note
(lambda (c) (error "~A" c
))))
2010 (compile nil
'(lambda (x)
2011 (declare (type simple-bit-vector x
))
2013 (with-test (:name
(:simple-bit-vector
:equal
:should-not-compiler-note
))
2014 (handler-bind ((sb-ext:compiler-note
(lambda (c) (error "~A" c
))))
2015 (compile nil
'(lambda (x y
)
2016 (declare (type simple-bit-vector x y
))
2019 ;;; MISC.550: CAST merging in IR1 finalization caused unexpected
2020 ;;; code transformations.
2021 (assert (eql (funcall
2025 (declare (optimize (speed 3) (safety 2) (debug 3) (space 3))
2028 (or p1
(the (eql t
) p2
))))
2032 ;;; MISC.548: type check weakening converts required type into
2039 (declare (optimize (speed 2) (safety 1) (debug 3) (space 2)))
2040 (atom (the (member f assoc-if write-line t w
) p1
))))
2043 ;;; Free special bindings only apply to the body of the binding form, not
2044 ;;; the initialization forms.
2046 (funcall (compile 'nil
2049 (declare (special x
))
2051 ((lambda (&optional
(y x
))
2052 (declare (special x
)) y
)))))))))
2054 ;;; Bug from pfdietz's random tester: the compiler knew that IMAGPART of
2055 ;;; a rational was zero, but didn't do the substitution, leading to a
2056 ;;; crash in the ASH vop (since a shift of 57 wouldn't fit in the
2057 ;;; machine's ASH instruction's immediate field) that the compiler
2058 ;;; thought was legitimate.
2059 (with-test (:name
:overlarge-immediate-in-ash-vop
)
2060 (checked-compile `(lambda (b)
2061 (declare (type (integer -
2 14) b
))
2062 (declare (ignorable b
))
2063 (ash (imagpart b
) 57))))
2065 ;;; bug reported by Eduardo Mu\~noz
2066 (with-test (:name
(compile vector loop
))
2068 `(lambda (struct first
)
2069 (declare (optimize speed
))
2070 (let* ((nodes (nodes struct
))
2071 (bars (bars struct
))
2072 (length (length nodes
))
2073 (new (make-array length
:fill-pointer
0)))
2074 (vector-push first new
)
2075 (loop with i fixnum
= 0
2076 for newl fixnum
= (length new
)
2077 while
(< newl length
) do
2078 (let ((oldl (length new
)))
2079 (loop for j fixnum from i below newl do
2080 (dolist (n (node-neighbours (aref new j
) bars
))
2081 (unless (find n new
)
2082 (vector-push n new
))))
2085 :allow-style-warnings t
))
2087 ;;; bug #389: "0.0 can't be converted to type NIL." (Brian Rowe
2089 (with-test (:name
(compile float
:bug-389
))
2090 (checked-compile `(lambda (x y a b c
)
2091 (- y
(* (signum x
) (sqrt (abs (- (* b x
) c
))))))
2092 :allow-style-warnings t
))
2094 ;;; Type inference from CHECK-TYPE
2095 (let ((count0 0) (count1 0))
2096 (handler-bind ((sb-ext:compiler-note
(lambda (c) (incf count0
))))
2097 (compile nil
'(lambda (x)
2098 (declare (optimize (speed 3)))
2100 ;; forced-to-do GENERIC-+, etc, possible word -> bignum conversion note
2101 (assert (> count0
1))
2102 (handler-bind ((sb-ext:compiler-note
(lambda (c) (incf count1
))))
2103 (compile nil
'(lambda (x)
2104 (declare (optimize (speed 3)))
2105 (check-type x fixnum
)
2107 ;; Only the posssible word -> bignum conversion note
2108 (assert (= count1
1)))
2110 ;;; Up to 0.9.8.22 x86-64 had broken return value handling in the
2111 ;;; %SET-SAP-REF-DOUBLE/SINGLE VOPs.
2112 (with-test (:name
:sap-ref-float
)
2113 (compile nil
'(lambda (sap)
2114 (let ((x (setf (sb-vm::sap-ref-double sap
0) 1d0
)))
2116 (compile nil
'(lambda (sap)
2117 (let ((x (setf (sb-vm::sap-ref-single sap
0) 1d0
)))
2121 (with-test (:name
:string-union-types
)
2122 (compile nil
'(lambda (x)
2123 (declare (type (or (simple-array character
(6))
2124 (simple-array character
(5))) x
))
2127 ;;; MISC.623: missing functions for constant-folding
2133 (declare (optimize (space 2) (speed 0) (debug 2)
2134 (compilation-speed 3) (safety 0)))
2135 (loop for lv3 below
1
2137 (loop for lv2 below
2
2139 (bit #*1001101001001
2140 (min 12 (max 0 lv3
))))))))))))
2142 ;;; MISC.624: erroneous AVER in x86's %LOGBITP VOPs
2148 (declare (type (integer 21 28) a
))
2149 (declare (optimize (compilation-speed 1) (safety 2)
2150 (speed 0) (debug 0) (space 1)))
2151 (let* ((v7 (flet ((%f3
(f3-1 f3-2
)
2152 (loop for lv2 below
1
2156 (min 7 (max 0 (eval '0))))))))
2161 ;;; MISC.626: bandaged AVER was still wrong
2162 (assert (eql -
829253
2167 (declare (type (integer -
902970 2) a
))
2168 (declare (optimize (space 2) (debug 0) (compilation-speed 1)
2169 (speed 0) (safety 3)))
2170 (prog2 (if (logbitp 30 a
) 0 (block b3
0)) a
)))
2173 ;; MISC.628: constant-folding %LOGBITP was buggy
2174 (with-test (:name
(compile logbitp
:constant-folding
))
2179 (declare (optimize (safety 3) (space 3) (compilation-speed 3)
2180 (speed 0) (debug 1)))
2181 (not (not (logbitp 0 (floor 2147483651 (min -
23 0)))))))))))
2183 ;; mistyping found by random-tester
2184 (with-test (:name
(compile :type-derivation
))
2189 (declare (optimize (speed 1) (debug 0)
2190 (space 2) (safety 0) (compilation-speed 0)))
2192 (* (/ (multiple-value-prog1 -
29457482 -
5602513511) 1)))))))))
2194 ;; aggressive constant folding (bug #400)
2195 (with-test (:name
(compile :aggressive-constant-folding
:bug-400
))
2197 (eq t
(funcall (checked-compile `(lambda () (or t
(the integer
(/ 1 0)))))))))
2199 (with-test (:name
(:compiler
:constraint-propagation
:var-eql-to-non-var-1
))
2200 (checked-compile `(lambda (x y
)
2201 (when (eql x
(length y
))
2203 (declare (optimize (speed 3)))
2205 :allow-notes
'(not compiler-note
)))
2207 (with-test (:name
(:compiler
:constraint-propagation
:var-eql-to-non-var-2
))
2208 (checked-compile `(lambda (x y
)
2209 (when (eql (length y
) x
)
2211 (declare (optimize (speed 3)))
2213 :allow-notes
'(not compiler-note
)))
2215 (with-test (:name
(:compiler
:constraint-propagation
:float-bounds-1
))
2216 (checked-compile `(lambda (x)
2217 (declare (type (single-float * (3.0
)) x
))
2221 :allow-notes
'(not compiler-note
)))
2223 (defun assert-code-deletion-note (lambda &optional
(howmany 1))
2224 (let ((notes (nth-value
2225 4 (checked-compile lambda
:allow-notes
'code-deletion-note
))))
2226 (assert (= howmany
(length notes
)))))
2228 (with-test (:name
(:compiler
:constraint-propagation
:float-bounds-2
))
2229 (assert-code-deletion-note
2231 (declare (type single-float x
))
2234 (error "This is unreachable."))))))
2236 (with-test (:name
(:compiler
:constraint-propagation
:float-bounds-3
2238 (assert-code-deletion-note
2240 (declare (type (single-float 0.0) x
))
2243 (error "This is unreachable."))))))
2245 (with-test (:name
(:compiler
:constraint-propagation
:float-bounds-4
2247 (assert-code-deletion-note
2249 (declare (type (single-float 0.0) x
)
2250 (type (single-float (0.0
)) y
))
2253 (error "This is unreachable."))))))
2255 (with-test (:name
(:compiler
:constraint-propagation
:var-eql-to-var-1
))
2256 (assert-code-deletion-note
2258 (when (typep y
'fixnum
)
2260 (unless (typep x
'fixnum
)
2261 (error "This is unreachable"))
2264 (with-test (:name
(:compiler
:constraint-propagation
:var-eql-to-var-2
))
2265 (assert-code-deletion-note
2267 (when (typep y
'fixnum
)
2269 (unless (typep x
'fixnum
)
2270 (error "This is unreachable"))
2273 ;; Reported by John Wiseman, sbcl-devel
2274 ;; Subject: [Sbcl-devel] float type derivation bug?
2275 ;; Date: Tue, 4 Apr 2006 15:28:15 -0700
2276 (with-test (:name
(compile :type-derivation
:float-bounds
))
2279 (let* ((s (if (= (ash bits -
31) 0) 1 -
1))
2280 (e (logand (ash bits -
23) #xff
))
2282 (ash (logand bits
#x7fffff
) 1)
2283 (logior (logand bits
#x7fffff
) #x800000
))))
2284 (float (* s m
(expt 2 (- e
150))))))))
2286 ;; Reported by James Knight
2287 ;; Subject: [Sbcl-devel] AVER: "(EQ (SB-NAME (SC-SB (TN-SC TN))) 'REGISTERS)"
2288 ;; Date: Fri, 24 Mar 2006 19:30:00 -0500
2289 (with-test (:name
(compile logbitp
:vop
))
2291 `(lambda (days shift
)
2292 (declare (type fixnum shift days
))
2294 (canonicalized-shift (+ shift
1))
2295 (first-wrapping-day (- 1 canonicalized-shift
)))
2296 (declare (type fixnum result
))
2297 (dotimes (source-day 7)
2298 (declare (type (integer 0 6) source-day
))
2299 (when (logbitp source-day days
)
2303 (if (< source-day first-wrapping-day
)
2304 (+ source-day canonicalized-shift
)
2306 canonicalized-shift
)
2310 ;;; MISC.637: incorrect delaying of conversion of optional entries
2311 ;;; with hairy constant defaults
2312 (with-test (:name
(compile :optional-entry
:hairy-defaults
:misc
.637))
2313 (let ((fun (checked-compile
2315 (labels ((%f11
(f11-2 &key key1
)
2316 (labels ((%f8
(f8-2 &optional
(f8-5 (if nil
(return-from %f11
0) 0)))
2321 (assert (eq (funcall fun
) :good
))))
2323 ;;; MISC.555: new reference to an already-optimized local function
2324 (with-test (:name
(compile :already-optimized
:local-function
:misc
.555))
2325 (let ((fun (checked-compile
2327 (declare (optimize (speed 1) (safety 2) (debug 2) (space 0))
2330 (assert (funcall fun
:good
))
2331 (assert-error (funcall fun
42) type-error
)))
2333 ;;; Check that the compiler doesn't munge *RANDOM-STATE*.
2334 (let* ((state (make-random-state))
2335 (*random-state
* (make-random-state state
))
2336 (a (random most-positive-fixnum
)))
2337 (setf *random-state
* state
)
2338 (compile nil
`(lambda (x a
)
2339 (declare (single-float x
)
2340 (type (simple-array double-float
) a
))
2341 (+ (loop for i across a
2344 (assert (= a
(random most-positive-fixnum
))))
2346 ;;; MISC.641: LET-conversion after physical environment analysis lost NLX-INFOs
2347 (with-test (:name
(compile let
:conversion
:lost
:nlx-infos
:misc
.641))
2348 (let ((fun (checked-compile
2350 (declare (optimize (speed 1) (space 0) (debug 2)
2351 (compilation-speed 0) (safety 1)))
2352 (flet ((%f3
(f3-1 &key
(key1 (count (floor 0 (min -
74 0)) #())))
2354 (apply #'%f3
0 nil
)))
2355 :allow-style-warnings t
)))
2356 (assert (zerop (funcall fun
)))))
2358 ;;; 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
2359 (with-test (:name
(compile make-array aref
:size-mismatch
))
2360 (checked-compile `(lambda ()
2361 (let ((x (make-array '(1) :element-type
'(signed-byte 32))))
2362 (setf (aref x
0) 1)))))
2364 ;;; step instrumentation confusing the compiler, reported by Faré
2365 (with-test (:name
(compile step
))
2366 (checked-compile `(lambda ()
2367 (declare (optimize (debug 2))) ; not debug 3!
2368 (let ((val "foobar"))
2369 (map-into (make-array (list (length val
))
2370 :element-type
'(unsigned-byte 8))
2371 #'char-code val
)))))
2373 ;;; overconfident primitive type computation leading to bogus type
2375 (with-test (:name
(compile :primitive-type standard-object condition function
))
2376 (flet ((test-case/incompatible
(type1 type2 object1 object2
)
2377 (multiple-value-bind (fun failure-p warnings
)
2380 (declare (type (and ,type1
,type2
) x
))
2382 :allow-failure t
:allow-warnings t
)
2384 (assert (= (length warnings
) 1))
2385 ;; FIXME (declare (type <equivalent-to-empty-type> x)) is
2386 ;; currently dropped instead of compiled into a type
2388 ;; (assert-error (funcall fun object1) type-error)
2389 ;; (assert-error (funcall fun object2) type-error)
2391 (test-case/compatible
(type1 type2 object1 object2
)
2392 (let ((fun (checked-compile
2394 (declare (type (and ,type1
,type2
) x
))
2396 (when (typep object1 type2
)
2397 (assert (typep (funcall fun object1
) type1
)))
2398 (when (typep object2 type1
)
2399 (assert (typep (funcall fun object2
) type2
))))))
2400 ;; TODO Add structure classes, SEQUENCE and EXTENDED-SEQUENCE
2401 (let ((types `((condition .
,(make-condition 'error
))
2402 (sb-kernel:funcallable-instance .
,#'print-object
)
2403 (function .
,#'identity
)
2404 (sb-kernel:instance .
,(find-class 'class
))
2405 (standard-object .
,(find-class 'class
))))
2406 (compatible '((sb-kernel:instance . condition
)
2407 (sb-kernel:instance . standard-object
)
2408 (sb-kernel:funcallable-instance . function
)
2409 (sb-kernel:funcallable-instance . standard-object
)
2410 (function . standard-object
))))
2411 (loop :for
(type1 . object1
) :in types
:do
2412 (loop :for
(type2 . object2
) :in types
:do
2414 (if (or (eq type1 type2
)
2415 (find-if (lambda (cell)
2416 (or (and (eq type1
(car cell
))
2417 (eq type2
(cdr cell
)))
2418 (and (eq type2
(car cell
))
2419 (eq type1
(cdr cell
)))))
2421 #'test-case
/compatible
2422 #'test-case
/incompatible
)
2423 type1 type2 object1 object2
))))))
2425 ;;; LET* + VALUES declaration: while the declaration is a non-standard
2426 ;;; and possibly a non-conforming extension, as long as we do support
2427 ;;; it, we might as well get it right.
2429 ;;; Bug reported by Kaersten Poeck on sbcl-devel 20061023.
2430 (compile nil
'(lambda () (let* () (declare (values list
)))))
2433 ;;; test for some problems with too large immediates in x86-64 modular
2435 (compile nil
'(lambda (x) (declare (fixnum x
))
2436 (logand most-positive-fixnum
(logxor x most-positive-fixnum
))))
2438 (compile nil
'(lambda (x) (declare (fixnum x
))
2439 (logand most-positive-fixnum
(+ x most-positive-fixnum
))))
2441 (compile nil
'(lambda (x) (declare (fixnum x
))
2442 (logand most-positive-fixnum
(* x most-positive-fixnum
))))
2445 (with-test (:name
:propagate-type-through-error-and-binding
)
2446 (assert (let (warned-p)
2447 (handler-bind ((warning (lambda (w) (setf warned-p t
))))
2450 (list (let ((y (the real x
)))
2451 (unless (floatp y
) (error ""))
2453 (integer-length x
)))))
2456 ;; Dead / in safe code
2457 (with-test (:name
:safe-dead-
/)
2460 (funcall (compile nil
2462 (declare (optimize (safety 3)))
2467 (division-by-zero ()
2470 ;;; Dead unbound variable (bug 412)
2471 (with-test (:name
:dead-unbound
)
2474 (funcall (compile nil
2478 (unbound-variable ()
2481 ;;; No compiler notes from compiling SUBSEQ SIMPLE-VECTOR.
2482 (handler-bind ((sb-ext:compiler-note
'error
))
2485 (funcall (compile nil
`(lambda (s p e
)
2486 (declare (optimize speed
)
2493 ;;; No compiler notes from compiling COPY-SEQ SIMPLE-VECTOR.
2494 (handler-bind ((sb-ext:compiler-note
'error
))
2497 (funcall (compile nil
`(lambda (s)
2498 (declare (optimize speed
)
2501 (vector 1 2 3 4)))))
2503 ;;; bug in adding DATA-VECTOR-REF-WITH-OFFSET to x86-64
2504 (assert (not (mismatch #(1.0f0
2.0f0
) (make-array 2 :element-type
'single-float
:initial-contents
(list 1.0f0
2.0f0
)))))
2506 ;;; bug in interval-arithmetic used by the compiler: needless attempt to coerce too
2507 ;;; large bignums to floats
2508 (dolist (op '(* / + -
))
2512 (declare (type (integer 0 #.
(* 2 (truncate most-positive-double-float
))) x
))
2515 do
(let ((arg (random (truncate most-positive-double-float
))))
2516 (assert (eql (funcall fun arg
)
2517 (funcall op
0.0d0 arg
)))))))
2519 (with-test (:name
:high-debug-known-function-inlining
)
2520 (let ((fun (compile nil
2522 (declare (optimize (debug 3)) (inline append
))
2523 (let ((fun (lambda (body)
2528 '((foo (bar)))))))))
2531 (with-test (:name
:high-debug-known-function-transform-with-optional-arguments
)
2532 (compile nil
'(lambda (x y
)
2533 (declare (optimize sb-c
::preserve-single-use-debug-variables
))
2535 (some-unknown-function
2537 (return (member x y
))))
2542 ;;; Compiling W-P-O when the pinned objects are known to be fixnums
2544 (compile nil
'(lambda (x y
)
2545 (declare (fixnum y
) (character x
))
2546 (sb-sys:with-pinned-objects
(x y
)
2547 (some-random-function))))
2549 ;;; *CHECK-CONSISTENCY* and TRULY-THE
2551 (with-test (:name
:bug-423
)
2552 (let ((sb-c::*check-consistency
* t
))
2553 (handler-bind ((warning #'error
))
2554 (flet ((make-lambda (type)
2558 (let ((q (truly-the list z
)))
2561 (let ((q (truly-the vector z
)))
2565 (compile nil
(make-lambda 'list
))
2566 (compile nil
(make-lambda 'vector
))))))
2568 ;;; this caused a momentary regression when an ill-adviced fix to
2569 ;;; bug 427 made ANY-REG suitable for primitive-type T:
2571 ;;; 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)
2572 ;;; [Condition of type SIMPLE-ERROR]
2579 (setf (sb-alien:deref
(sb-alien:cast
(sb-alien:sap-alien
(unknown1) (* unsigned-char
))
2580 (* double-float
))) frob
))
2582 (%zig
(the (values (single-float (0.0
) 1.0) &optional
) (unknown2)))
2586 ;;; non-required arguments in HANDLER-BIND
2587 (assert (eq :oops
(car (funcall (compile nil
2590 (handler-bind ((error (lambda (&rest args
) (return (cons :oops args
)))))
2594 ;;; NIL is a legal function name
2595 (assert (eq 'a
(flet ((nil () 'a
)) (nil))))
2598 (assert (null (let* ((x 296.3066f0
)
2600 (form `(lambda (r p2
)
2601 (declare (optimize speed
(safety 1))
2602 (type (simple-array single-float nil
) r
)
2603 (type (integer -
9369756340 22717335) p2
))
2604 (setf (aref r
) (* ,x
(the (eql 22717067) p2
)))
2606 (r (make-array nil
:element-type
'single-float
))
2608 (funcall (compile nil form
) r y
)
2609 (let ((actual (aref r
)))
2610 (unless (eql expected actual
)
2611 (list expected actual
))))))
2613 (assert (null (let* ((x -
2367.3296f0
)
2615 (form `(lambda (r p2
)
2616 (declare (optimize speed
(safety 1))
2617 (type (simple-array single-float nil
) r
)
2618 (type (eql 46790178) p2
))
2619 (setf (aref r
) (+ ,x
(the (integer 45893897) p2
)))
2621 (r (make-array nil
:element-type
'single-float
))
2623 (funcall (compile nil form
) r y
)
2624 (let ((actual (aref r
)))
2625 (unless (eql expected actual
)
2626 (list expected actual
))))))
2631 (compile nil
'(lambda (p1 p2
)
2633 (optimize (speed 1) (safety 0)
2634 (debug 0) (space 0))
2635 (type (member 8174.8604) p1
)
2636 (type (member -
95195347) p2
))
2638 8174.8604 -
95195347)))
2646 (declare (optimize (speed 3) (safety 0) (debug 3) (space 1))
2647 (type (member -
94430.086f0
) p1
))
2648 (floor (the single-float p1
) 19311235)))
2657 (declare (optimize (speed 1) (safety 2)
2658 (debug 2) (space 3))
2659 (type (eql -
39466.56f0
) p1
))
2660 (ffloor p1
305598613)))
2669 (declare (optimize (speed 1) (safety 1) (debug 1) (space 2))
2670 (type (eql -
83232.09f0
) p1
))
2671 (ceiling p1 -
83381228)))
2680 (declare (optimize (speed 1) (safety 1)
2681 (debug 1) (space 0))
2682 (type (member -
66414.414f0
) p1
))
2683 (ceiling p1 -
63019173f0
)))
2692 (declare (optimize (speed 0) (safety 1)
2693 (debug 0) (space 1))
2694 (type (eql 20851.398f0
) p1
))
2695 (fceiling p1
80839863)))
2701 (compile nil
'(lambda (x)
2702 (declare (type (eql -
5067.2056) x
))
2709 (compile nil
'(lambda (x) (declare (type (eql -
1.0) x
))
2715 (assert (plusp (funcall
2719 (declare (optimize (speed 0) (safety 1) (debug 1) (space 1))
2720 (type (eql -
39887.645) p1
))
2721 (mod p1
382352925)))
2725 (assert (let ((result (funcall
2729 (declare (optimize (speed 0) (safety 3) (debug 1) (space 0))
2730 (type (eql 33558541) p2
))
2733 (typep result
'single-float
)))
2737 (let* ((form '(lambda (p2)
2738 (declare (optimize (speed 0) (safety 1)
2739 (debug 2) (space 2))
2740 (type (member -
19261719) p2
))
2741 (ceiling -
46022.094 p2
))))
2742 (values (funcall (compile nil form
) -
19261719)))))
2745 (assert (let* ((x 26899.875)
2747 (declare (optimize (speed 3) (safety 1) (debug 3) (space 1))
2748 (type (member ,x
#:g5437 char-code
#:g5438
) p2
))
2750 (floatp (funcall (compile nil form
) x
))))
2758 (declare (optimize (speed 3) (safety 2) (debug 3) (space 0))
2760 (+ 81535869 (the (member 17549.955 #:g35917
) p2
))))
2762 (+ 81535869 17549.955)))
2766 (let ((form '(lambda (p2)
2767 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2768 (type (member integer eql
) p2
))
2770 (funcall (compile nil form
) 'integer
))))
2774 (let ((form '(lambda (p2)
2775 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2776 (type (member integer mod
) p2
))
2778 (funcall (compile nil form
) 'integer
))))
2782 (let ((form '(lambda (p2)
2783 (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
2784 (type (member integer values
) p2
))
2786 (funcall (compile nil form
) 'integer
))))
2788 (with-test (:name
:string-aref-type
)
2789 (assert (eq 'character
2790 (funcall (compile nil
2792 (ctu:compiler-derived-type
(aref (the string s
) 0))))
2795 (with-test (:name
:base-string-aref-type
)
2796 (assert (eq #+sb-unicode
'base-char
2797 #-sb-unicode
'character
2798 (funcall (compile nil
2800 (ctu:compiler-derived-type
(aref (the base-string s
) 0))))
2801 (coerce "foo" 'base-string
)))))
2803 (with-test (:name
:dolist-constant-type-derivation
)
2804 (assert (equal '(integer 1 3)
2805 (funcall (compile nil
2807 (dolist (y '(1 2 3))
2809 (return (ctu:compiler-derived-type y
))))))
2812 (with-test (:name
:dolist-simple-list-type-derivation
)
2813 (assert (equal '(integer 1 3)
2814 (funcall (compile nil
2816 (dolist (y (list 1 2 3))
2818 (return (ctu:compiler-derived-type y
))))))
2821 (with-test (:name
:dolist-dotted-constant-list-type-derivation
)
2823 (fun (handler-bind ((style-warning (lambda (c) (push c warned
))))
2826 (dolist (y '(1 2 3 .
4) :foo
)
2828 (return (ctu:compiler-derived-type y
)))))))))
2829 (assert (equal '(integer 1 3) (funcall fun t
)))
2830 (assert (= 1 (length warned
)))
2831 (multiple-value-bind (res err
) (ignore-errors (funcall fun nil
))
2833 (assert (typep err
'type-error
)))))
2835 (with-test (:name
:constant-list-destructuring
)
2836 (handler-bind ((sb-ext:compiler-note
#'error
))
2842 (destructuring-bind (a (b c
) d
) '(1 (2 3) 4)
2849 (destructuring-bind (a (b c
) d
) '(1 "foo" 4)
2853 ;;; Functions with non-required arguments used to end up with
2854 ;;; (&OPTIONAL-DISPATCH ...) as their names.
2855 (with-test (:name
:hairy-function-name
)
2856 (assert (eq 'read-line
(nth-value 2 (function-lambda-expression #'read-line
))))
2857 (assert (equal "#<FUNCTION READ-LINE>" (princ-to-string #'read-line
))))
2859 ;;; PROGV + RESTRICT-COMPILER-POLICY
2860 ;; META: there's a test in compiler.impure.lisp that also tests
2861 ;; interaction of PROGV with (debug 3). These tests should be together.
2862 (with-test (:name
:progv-and-restrict-compiler-policy
)
2863 (let ((sb-c::*policy-restrictions
* sb-c
::*policy-restrictions
*))
2864 (restrict-compiler-policy 'debug
3)
2865 (let ((fun (compile nil
'(lambda (x)
2867 (declare (special i
))
2869 (progv '(i) (list (+ i
1))
2872 (assert (equal '(1 2 1) (funcall fun
1))))))
2874 ;;; It used to be possible to confuse the compiler into
2875 ;;; IR2-converting such a call to CONS
2876 (with-test (:name
:late-bound-primitive
)
2877 (compile nil
`(lambda ()
2878 (funcall 'cons
1))))
2880 (with-test (:name
:hairy-array-element-type-derivation
)
2881 (compile nil
'(lambda (x)
2882 (declare (type (and simple-string
(satisfies array-has-fill-pointer-p
)) x
))
2883 (array-element-type x
))))
2885 (with-test (:name
:rest-list-type-derivation
)
2886 (multiple-value-bind (type derivedp
)
2887 (funcall (compile nil
`(lambda (&rest args
)
2888 (ctu:compiler-derived-type args
)))
2890 (assert (eq 'list type
))
2893 (with-test (:name
:rest-list-type-derivation2
)
2894 (multiple-value-bind (type derivedp
)
2895 (funcall (funcall (compile nil
`(lambda ()
2896 (lambda (&rest args
)
2897 (ctu:compiler-derived-type args
))))))
2898 (assert (eq 'list type
))
2901 (with-test (:name
:rest-list-type-derivation3
)
2902 (multiple-value-bind (type derivedp
)
2903 (funcall (funcall (compile nil
`(lambda ()
2904 (lambda (&optional x
&rest args
)
2905 (unless x
(error "oops"))
2906 (ctu:compiler-derived-type args
)))))
2908 (assert (eq 'list type
))
2911 (with-test (:name
:rest-list-type-derivation4
)
2912 (multiple-value-bind (type derivedp
)
2913 (funcall (funcall (compile nil
`(lambda ()
2914 (lambda (&optional x
&rest args
)
2915 (declare (type (or null integer
) x
))
2916 (when x
(setf args x
))
2917 (ctu:compiler-derived-type args
)))))
2919 (assert (equal '(or cons null integer
) type
))
2922 (with-test (:name
:base-char-typep-elimination
)
2923 (assert (eq (funcall (compile nil
2925 (declare (type base-char ch
) (optimize (speed 3) (safety 0)))
2926 (typep ch
'base-char
)))
2930 (with-test (:name
:regression-1.0
.24.37)
2931 (checked-compile `(lambda (&key
(test (constantly t
)))
2932 (when (funcall test
)
2935 ;;; Attempt to test a decent cross section of conditions
2936 ;;; and values types to move conditionally.
2938 ((test-comparison (comparator type x y
)
2940 ,@(loop for
(result-type a b
)
2946 (nil #c
(1.0
1.0) #c
(2.0
2.0))
2950 ((unsigned-byte #.sb-vm
:n-word-bits
)
2951 (1+ most-positive-fixnum
)
2952 (+ 2 most-positive-fixnum
))
2953 ((signed-byte #.sb-vm
:n-word-bits
)
2954 -
1 (* 2 most-negative-fixnum
))
2955 (single-float 0.0 1.0)
2956 (double-float 0d0
1d0
))
2957 for lambda
= (if result-type
2959 (declare (,type x y
)
2961 (if (,comparator x y
)
2964 (declare (,type x y
))
2965 (if (,comparator x y
)
2967 for args
= `(,x
,y
,@(and result-type
2971 (eql (funcall (checked-compile ',lambda
)
2973 (eval '(,lambda
,@args
))))))))
2974 (sb-vm::with-float-traps-masked
2975 (:divide-by-zero
:overflow
:inexact
:invalid
)
2976 (let (#+sb-eval
(sb-ext:*evaluator-mode
* :interpret
))
2977 (declare (sb-ext:muffle-conditions style-warning
))
2978 (test-comparison eql t t nil
)
2979 (test-comparison eql t t t
)
2981 (test-comparison = t
1 0)
2982 (test-comparison = t
1 1)
2983 (test-comparison = t
(1+ most-positive-fixnum
) (+ 2 most-positive-fixnum
))
2984 (test-comparison = fixnum
1 0)
2985 (test-comparison = fixnum
0 0)
2986 (test-comparison = (unsigned-byte #.sb-vm
:n-word-bits
) 1 0)
2987 (test-comparison = (unsigned-byte #.sb-vm
:n-word-bits
) 0 0)
2988 (test-comparison = (signed-byte #.sb-vm
:n-word-bits
) 1 0)
2989 (test-comparison = (signed-byte #.sb-vm
:n-word-bits
) 1 1)
2991 (test-comparison = single-float
0.0 1.0)
2992 (test-comparison = single-float
1.0 1.0)
2993 (test-comparison = single-float
(/ 1.0 0.0) (/ 1.0 0.0))
2994 (test-comparison = single-float
(/ 1.0 0.0) 1.0)
2995 (test-comparison = single-float
(/ 0.0 0.0) (/ 0.0 0.0))
2996 (test-comparison = single-float
(/ 0.0 0.0) 0.0)
2998 (test-comparison = double-float
0d0
1d0
)
2999 (test-comparison = double-float
1d0
1d0
)
3000 (test-comparison = double-float
(/ 1d0
0d0
) (/ 1d0
0d0
))
3001 (test-comparison = double-float
(/ 1d0
0d0
) 1d0
)
3002 (test-comparison = double-float
(/ 0d0
0d0
) (/ 0d0
0d0
))
3003 (test-comparison = double-float
(/ 0d0
0d0
) 0d0
)
3005 (test-comparison < t
1 0)
3006 (test-comparison < t
0 1)
3007 (test-comparison < t
1 1)
3008 (test-comparison < t
(1+ most-positive-fixnum
) (+ 2 most-positive-fixnum
))
3009 (test-comparison < t
(+ 2 most-positive-fixnum
) (1+ most-positive-fixnum
))
3010 (test-comparison < fixnum
1 0)
3011 (test-comparison < fixnum
0 1)
3012 (test-comparison < fixnum
0 0)
3013 (test-comparison < (unsigned-byte #.sb-vm
:n-word-bits
) 1 0)
3014 (test-comparison < (unsigned-byte #.sb-vm
:n-word-bits
) 0 1)
3015 (test-comparison < (unsigned-byte #.sb-vm
:n-word-bits
) 0 0)
3016 (test-comparison < (signed-byte #.sb-vm
:n-word-bits
) 1 0)
3017 (test-comparison < (signed-byte #.sb-vm
:n-word-bits
) 0 1)
3018 (test-comparison < (signed-byte #.sb-vm
:n-word-bits
) 1 1)
3020 (test-comparison < single-float
0.0 1.0)
3021 (test-comparison < single-float
1.0 0.0)
3022 (test-comparison < single-float
1.0 1.0)
3023 (test-comparison < single-float
(/ 1.0 0.0) (/ 1.0 0.0))
3024 (test-comparison < single-float
(/ 1.0 0.0) 1.0)
3025 (test-comparison < single-float
1.0 (/ 1.0 0.0))
3026 (test-comparison < single-float
(/ 0.0 0.0) (/ 0.0 0.0))
3027 (test-comparison < single-float
(/ 0.0 0.0) 0.0)
3029 (test-comparison < double-float
0d0
1d0
)
3030 (test-comparison < double-float
1d0
0d0
)
3031 (test-comparison < double-float
1d0
1d0
)
3032 (test-comparison < double-float
(/ 1d0
0d0
) (/ 1d0
0d0
))
3033 (test-comparison < double-float
(/ 1d0
0d0
) 1d0
)
3034 (test-comparison < double-float
1d0
(/ 1d0
0d0
))
3035 (test-comparison < double-float
(/ 0d0
0d0
) (/ 0d0
0d0
))
3036 (test-comparison < double-float
(/ 0d0
0d0
) 0d0
)
3037 (test-comparison < double-float
0d0
(/ 0d0
0d0
))
3039 (test-comparison > t
1 0)
3040 (test-comparison > t
0 1)
3041 (test-comparison > t
1 1)
3042 (test-comparison > t
(1+ most-positive-fixnum
) (+ 2 most-positive-fixnum
))
3043 (test-comparison > t
(+ 2 most-positive-fixnum
) (1+ most-positive-fixnum
))
3044 (test-comparison > fixnum
1 0)
3045 (test-comparison > fixnum
0 1)
3046 (test-comparison > fixnum
0 0)
3047 (test-comparison > (unsigned-byte #.sb-vm
:n-word-bits
) 1 0)
3048 (test-comparison > (unsigned-byte #.sb-vm
:n-word-bits
) 0 1)
3049 (test-comparison > (unsigned-byte #.sb-vm
:n-word-bits
) 0 0)
3050 (test-comparison > (signed-byte #.sb-vm
:n-word-bits
) 1 0)
3051 (test-comparison > (signed-byte #.sb-vm
:n-word-bits
) 0 1)
3052 (test-comparison > (signed-byte #.sb-vm
:n-word-bits
) 1 1)
3054 (test-comparison > single-float
0.0 1.0)
3055 (test-comparison > single-float
1.0 0.0)
3056 (test-comparison > single-float
1.0 1.0)
3057 (test-comparison > single-float
(/ 1.0 0.0) (/ 1.0 0.0))
3058 (test-comparison > single-float
(/ 1.0 0.0) 1.0)
3059 (test-comparison > single-float
1.0 (/ 1.0 0.0))
3060 (test-comparison > single-float
(/ 0.0 0.0) (/ 0.0 0.0))
3061 (test-comparison > single-float
(/ 0.0 0.0) 0.0)
3063 (test-comparison > double-float
0d0
1d0
)
3064 (test-comparison > double-float
1d0
0d0
)
3065 (test-comparison > double-float
1d0
1d0
)
3066 (test-comparison > double-float
(/ 1d0
0d0
) (/ 1d0
0d0
))
3067 (test-comparison > double-float
(/ 1d0
0d0
) 1d0
)
3068 (test-comparison > double-float
1d0
(/ 1d0
0d0
))
3069 (test-comparison > double-float
(/ 0d0
0d0
) (/ 0d0
0d0
))
3070 (test-comparison > double-float
(/ 0d0
0d0
) 0d0
)
3071 (test-comparison > double-float
0d0
(/ 0d0
0d0
)))))
3073 (with-test (:name
:car-and-cdr-type-derivation-conservative
)
3074 (let ((f1 (checked-compile
3076 (declare (optimize speed
))
3077 (let ((x (the (cons fixnum fixnum
) (cons 1 2))))
3078 (declare (type (cons t fixnum
) x
))
3080 (+ (car x
) (cdr x
))))))
3081 (f2 (checked-compile
3083 (declare (optimize speed
))
3084 (let ((x (the (cons fixnum fixnum
) (cons 1 2))))
3086 (+ (car x
) (cdr x
)))))))
3087 (flet ((test-error (e value
)
3088 (assert (typep e
'type-error
))
3089 (assert (eq 'number
(type-error-expected-type e
)))
3090 (assert (eq value
(type-error-datum e
)))))
3093 (multiple-value-bind (res err
) (ignore-errors (funcall f1 v1
))
3095 (test-error err v1
))
3096 (multiple-value-bind (res err
) (ignore-errors (funcall f2 v2
))
3098 (test-error err v2
))))))
3100 (with-test (:name
:array-dimension-derivation-conservative
)
3101 (let ((f (checked-compile `(lambda (x)
3102 (declare (optimize speed
))
3103 (declare (type (array * (4 4)) x
))
3105 (setq x
(make-array '(4 4)))
3106 (adjust-array y
'(3 5))
3107 (array-dimension y
0))))))
3108 (assert (= 3 (funcall f
(make-array '(4 4) :adjustable t
))))))
3110 (with-test (:name
:with-timeout-code-deletion-note
)
3111 (checked-compile `(lambda ()
3112 (sb-ext:with-timeout
0
3116 (with-test (:name
:full-warning-for-undefined-type-in-cl
)
3117 (multiple-value-bind (fun failure-p warnings
)
3118 (checked-compile `(lambda (x) (the replace x
)) :allow-warnings t
)
3119 (declare (ignore fun failure-p
))
3120 (assert (= 1 (length warnings
)))))
3122 (with-test (:name
:single-warning-for-single-undefined-type
)
3123 ;; STYLE-WARNING for symbol not in cl package.
3124 (multiple-value-bind (fun failure-p warnings style-warnings
)
3125 (checked-compile `(lambda (x) (the #:no-type x
))
3126 :allow-style-warnings t
)
3127 (declare (ignore fun failure-p warnings
))
3128 (assert (= 1 (length style-warnings
))))
3130 ;; Full WARNING for invalid type specifier starting with QUOTE.
3131 (multiple-value-bind (fun failure-p warnings
)
3132 (checked-compile `(lambda (x) (the 'fixnum x
)) :allow-warnings t
)
3133 (declare (ignore fun failure-p
))
3134 (assert (= 1 (length warnings
)))))
3136 (with-test (:name
:complex-subtype-dumping-in-xc
)
3138 (= sb-vm
:complex-single-float-widetag
3139 (sb-kernel:widetag-of
3140 (sb-vm:saetp-initial-element-default
(sb-c::find-saetp
'(complex single-float
))))))
3142 (= sb-vm
:complex-double-float-widetag
3143 (sb-kernel:widetag-of
3144 (sb-vm:saetp-initial-element-default
(sb-c::find-saetp
'(complex double-float
)))))))
3146 (with-test (:name
:complex-single-float-fill
)
3147 (assert (every (lambda (x) (= #c
(1.0
2.0) x
))
3151 (make-array (list n
)
3152 :element-type
'(complex single-float
)
3153 :initial-element x
)))
3157 (with-test (:name
:regression-1.0
.28.21)
3158 (let ((fun (compile nil
`(lambda (x) (typep x
'(simple-array * 1))))))
3159 (assert (funcall fun
(vector 1 2 3)))
3160 (assert (funcall fun
"abc"))
3161 (assert (not (funcall fun
(make-array '(2 2)))))))
3163 (with-test (:name
:no-silly-compiler-notes-from-character-function
)
3164 (dolist (name '(char-code char-int character char-name standard-char-p
3165 graphic-char-p alpha-char-p upper-case-p lower-case-p
3166 both-case-p digit-char-p alphanumericp digit-char-p
))
3167 (checked-compile `(lambda (x)
3168 (declare (character x
) (optimize (speed 3)))
3171 (dolist (name '(char= char
/= char
< char
> char
<= char
>=
3172 char-lessp char-greaterp char-not-greaterp
3174 (checked-compile `(lambda (x y
)
3175 (declare (character x y
) (optimize speed
))
3179 ;;; optimizing make-array
3180 (with-test (:name
(make-array :open-code-initial-contents
))
3182 (assert (not (ctu:find-named-callees
3183 (checked-compile form
))))))
3184 (test `(lambda (x y z
)
3185 (make-array '(3) :initial-contents
(list x y z
))))
3186 (test `(lambda (x y z
)
3187 (make-array '3 :initial-contents
(vector x y z
))))
3188 (test `(lambda (x y z
)
3189 (make-array '3 :initial-contents
`(,x
,y
,z
))))
3190 (test `(lambda (x y z
)
3191 ;; Single-use FLET is eliminated,
3192 ;; so MAKE-ARRAY's result is obviously a vector.
3193 (flet ((size () '(3)))
3194 (make-array (size) :initial-contents
`(,x
,y
,z
)))))
3195 (test `(lambda (x y z
)
3196 (flet ((size () (list 3))) ; here too
3197 (make-array (size) :initial-contents
`(,x
,y
,z
)))))))
3199 ;;; optimizing array-in-bounds-p
3200 (with-test (:name
:optimize-array-in-bounds-p
)
3202 (macrolet ((find-callees (&body body
)
3203 `(ctu:find-named-callees
3204 (checked-compile '(lambda () ,@body
))
3205 :name
'array-in-bounds-p
))
3206 (must-optimize (&body exprs
)
3208 ,@(loop for expr in exprs
3209 collect
`(assert (not (find-callees
3211 (must-not-optimize (&body exprs
)
3213 ,@(loop for expr in exprs
3214 collect
`(assert (find-callees
3218 (let ((a (make-array '(1))))
3219 (array-in-bounds-p a
0))
3220 ;; exceeds upper bound (constant)
3221 (let ((a (make-array '(1))))
3222 (array-in-bounds-p a
1))
3223 ;; exceeds upper bound (interval)
3224 (let ((a (make-array '(1))))
3225 (array-in-bounds-p a
(+ 1 (random 2))))
3226 ;; negative lower bound (constant)
3227 (let ((a (make-array '(1))))
3228 (array-in-bounds-p a -
1))
3229 ;; negative lower bound (interval)
3230 (let ((a (make-array 3))
3231 (i (- (random 1) 20)))
3232 (array-in-bounds-p a i
))
3233 ;; multiple known dimensions
3234 (let ((a (make-array '(1 1))))
3235 (array-in-bounds-p a
0 0))
3237 (let ((s (the (simple-string 10) (eval "0123456789"))))
3238 (array-in-bounds-p s
9)))
3240 ;; don't trust non-simple array length in safety=1
3241 (let ((a (the (array * (10 20)) (make-array '(10 20) :adjustable t
))))
3242 (eval `(adjust-array ,a
'(0 0)))
3243 (array-in-bounds-p a
9 0))
3244 ;; multiple unknown dimensions
3245 (let ((a (make-array (list (random 20) (random 5)))))
3246 (array-in-bounds-p a
5 2))
3247 ;; some other known dimensions
3248 (let ((a (make-array (list 1 (random 5)))))
3249 (array-in-bounds-p a
0 2))
3250 ;; subscript might be negative
3251 (let ((a (make-array '(5 10))))
3252 (array-in-bounds-p a
1 (- (random 3) 2)))
3253 ;; subscript might be too large
3254 (let ((a (make-array '(5 10))))
3255 (array-in-bounds-p a
(random 6) 1))
3256 ;; unknown upper bound
3257 (let ((a (make-array '(5 10))))
3258 (array-in-bounds-p a
(get-universal-time) 1))
3259 ;; unknown lower bound
3260 (let ((a (make-array '(5 30))))
3261 (array-in-bounds-p a
0 (- (get-universal-time))))
3262 ;; in theory we should be able to optimize
3263 ;; the following but the current implementation
3264 ;; doesn't cut it because the array type's
3265 ;; dimensions get reported as (* *).
3266 (let ((a (make-array (list (random 20) 1))))
3267 (array-in-bounds-p a
5 2))))))
3269 ;;; optimizing (EXPT -1 INTEGER)
3270 (with-test (:name
(expt -
1 integer
))
3271 (dolist (x '(-1 -
1.0 -
1.0d0
))
3272 (let ((fun (checked-compile `(lambda (x) (expt ,x
(the fixnum x
))))))
3273 (assert (not (ctu:find-named-callees fun
)))
3276 (assert (eql x
(funcall fun i
)))
3277 (assert (eql (- x
) (funcall fun i
))))))))
3279 (with-test (:name
:float-division-using-exact-reciprocal
)
3280 (flet ((test (lambda-form arg res
&key
(check-insts t
))
3281 (let* ((fun (checked-compile lambda-form
))
3282 (disassembly (with-output-to-string (s)
3283 (disassemble fun
:stream s
))))
3284 ;; Let's make sure there is no division at runtime: for x86 and
3285 ;; x86-64 that implies an FDIV, DIVSS, or DIVSD instruction, so
3286 ;; look for DIV in the disassembly. It's a terrible KLUDGE, but
3290 (assert (not (search "DIV" disassembly
))))
3291 ;; No generic arithmetic!
3292 (assert (not (search "GENERIC" disassembly
)))
3293 (assert (eql res
(funcall fun arg
))))))
3294 (dolist (c '(128 64 32 16 8 4 2 1 1/2 1/4 1/8 1/16 1/32 1/64))
3295 (dolist (type '(single-float double-float
))
3296 (let* ((cf (coerce c type
))
3297 (arg (- (random (* 2 cf
)) cf
))
3298 (r1 (eval `(/ ,arg
,cf
)))
3299 (r2 (eval `(/ ,arg
,(- cf
)))))
3300 (test `(lambda (x) (declare (,type x
)) (/ x
,cf
)) arg r1
)
3301 (test `(lambda (x) (declare (,type x
)) (/ x
,(- cf
))) arg r2
)
3302 ;; rational args should get optimized as well
3303 (test `(lambda (x) (declare (,type x
)) (/ x
,c
)) arg r1
)
3304 (test `(lambda (x) (declare (,type x
)) (/ x
,(- c
))) arg r2
))))
3305 ;; Also check that inexact reciprocals (1) are not used by default (2) are
3306 ;; used with FLOAT-ACCURACY=0.
3307 (dolist (type '(single-float double-float
))
3308 (let ((trey (coerce 3 type
))
3309 (one (coerce 1 type
)))
3310 (test `(lambda (x) (declare (,type x
)) (/ x
3)) trey one
3314 (optimize (sb-c::float-accuracy
0)))
3316 trey
(eval `(* ,trey
(/ ,trey
))))))))
3318 (with-test (:name
:float-multiplication-by-one
)
3319 (flet ((test (lambda-form arg
&optional
(result arg
))
3320 (let* ((fun1 (checked-compile lambda-form
))
3321 (fun2 (funcall (checked-compile
3323 (declare (optimize (sb-c::float-accuracy
0)))
3325 (disassembly1 (with-output-to-string (s)
3326 (disassemble fun1
:stream s
)))
3327 (disassembly2 (with-output-to-string (s)
3328 (disassemble fun2
:stream s
))))
3329 ;; Multiplication at runtime should be eliminated only with
3330 ;; FLOAT-ACCURACY=0. (To catch SNaNs.)
3332 (assert (and (search "MUL" disassembly1
)
3333 (not (search "MUL" disassembly2
))))
3334 ;; Not generic arithmetic, please!
3335 (assert (and (not (search "GENERIC" disassembly1
))
3336 (not (search "GENERIC" disassembly2
))))
3337 (assert (eql result
(funcall fun1 arg
)))
3338 (assert (eql result
(funcall fun2 arg
))))))
3339 (dolist (type '(single-float double-float
))
3340 (let* ((one (coerce 1 type
))
3341 (arg (random (* 2 one
)))
3343 (test `(lambda (x) (declare (,type x
)) (* x
1)) arg
)
3344 (test `(lambda (x) (declare (,type x
)) (* x -
1)) arg -r
)
3345 (test `(lambda (x) (declare (,type x
)) (* x
,one
)) arg
)
3346 (test `(lambda (x) (declare (,type x
)) (* x
,(- one
))) arg -r
)))))
3348 (with-test (:name
:float-addition-of-zero
)
3349 (flet ((test (lambda-form arg
&optional
(result arg
))
3350 (let* ((fun1 (checked-compile lambda-form
))
3351 (fun2 (funcall (checked-compile
3353 (declare (optimize (sb-c::float-accuracy
0)))
3355 (disassembly1 (with-output-to-string (s)
3356 (disassemble fun1
:stream s
)))
3357 (disassembly2 (with-output-to-string (s)
3358 (disassemble fun2
:stream s
))))
3359 ;; Let's make sure there is no addition at runtime: for x86 and
3360 ;; x86-64 that implies an FADD, ADDSS, or ADDSD instruction, so
3361 ;; look for the ADDs in the disassembly. It's a terrible KLUDGE,
3362 ;; but it works. Unless FLOAT-ACCURACY is zero, we leave the
3363 ;; addition in to catch SNaNs.
3365 (assert (and (search "FADD" disassembly1
)
3366 (not (search "FADD" disassembly2
))))
3368 (let ((inst (if (typep result
'double-float
)
3370 (assert (and (search inst disassembly1
)
3371 (not (search inst disassembly2
)))))
3372 (assert (eql result
(funcall fun1 arg
)))
3373 (assert (eql result
(funcall fun2 arg
))))))
3374 (test `(lambda (x) (declare (single-float x
)) (+ x
0)) 123.45)
3375 (test `(lambda (x) (declare (single-float x
)) (+ x
0.0)) 543.21)
3376 (test `(lambda (x) (declare (single-float x
)) (+ x
0.0d0
)) 42.00 42.d0
)
3377 (test `(lambda (x) (declare (double-float x
)) (+ x
0)) 123.45d0
)
3378 (test `(lambda (x) (declare (double-float x
)) (+ x
0.0)) 543.21d0
)
3379 (test `(lambda (x) (declare (double-float x
)) (+ x
0.0d0
)) 42.d0
)))
3381 (with-test (:name
:float-substraction-of-zero
)
3382 (flet ((test (lambda-form arg
&optional
(result arg
))
3383 (let* ((fun1 (compile nil lambda-form
))
3384 (fun2 (funcall (compile nil
`(lambda ()
3385 (declare (optimize (sb-c::float-accuracy
0)))
3387 (disassembly1 (with-output-to-string (s)
3388 (disassemble fun1
:stream s
)))
3389 (disassembly2 (with-output-to-string (s)
3390 (disassemble fun2
:stream s
))))
3391 ;; Let's make sure there is no substraction at runtime: for x86
3392 ;; and x86-64 that implies an FSUB, SUBSS, or SUBSD instruction,
3393 ;; so look for SUB in the disassembly. It's a terrible KLUDGE,
3394 ;; but it works. Unless FLOAT-ACCURACY is zero, we leave the
3395 ;; substraction in in to catch SNaNs.
3397 (assert (and (search "FSUB" disassembly1
)
3398 (not (search "FSUB" disassembly2
))))
3400 (let ((inst (if (typep result
'double-float
)
3402 (assert (and (search inst disassembly1
)
3403 (not (search inst disassembly2
)))))
3404 (assert (eql result
(funcall fun1 arg
)))
3405 (assert (eql result
(funcall fun2 arg
))))))
3406 (test `(lambda (x) (declare (single-float x
)) (- x
0)) 123.45)
3407 (test `(lambda (x) (declare (single-float x
)) (- x
0.0)) 543.21)
3408 (test `(lambda (x) (declare (single-float x
)) (- x
0.0d0
)) 42.00 42.d0
)
3409 (test `(lambda (x) (declare (double-float x
)) (- x
0)) 123.45d0
)
3410 (test `(lambda (x) (declare (double-float x
)) (- x
0.0)) 543.21d0
)
3411 (test `(lambda (x) (declare (double-float x
)) (- x
0.0d0
)) 42.d0
)))
3413 (with-test (:name
:float-multiplication-by-two
)
3414 (flet ((test (lambda-form arg
&optional
(result arg
))
3415 (let* ((fun1 (compile nil lambda-form
))
3416 (fun2 (funcall (compile nil
`(lambda ()
3417 (declare (optimize (sb-c::float-accuracy
0)))
3419 (disassembly1 (with-output-to-string (s)
3420 (disassemble fun1
:stream s
)))
3421 (disassembly2 (with-output-to-string (s)
3422 (disassemble fun2
:stream s
))))
3423 ;; Let's make sure there is no multiplication at runtime: for x86
3424 ;; and x86-64 that implies an FMUL, MULSS, or MULSD instruction,
3425 ;; so look for MUL in the disassembly. It's a terrible KLUDGE,
3428 (assert (and (not (search "MUL" disassembly1
))
3429 (not (search "MUL" disassembly2
))))
3430 (assert (eql result
(funcall fun1 arg
)))
3431 (assert (eql result
(funcall fun2 arg
))))))
3432 (test `(lambda (x) (declare (single-float x
)) (* x
2)) 123.45 246.9)
3433 (test `(lambda (x) (declare (single-float x
)) (* x
2.0)) 543.21 1086.42)
3434 (test `(lambda (x) (declare (single-float x
)) (* x
2.0d0
)) 42.00 84.d0
)
3435 (test `(lambda (x) (declare (double-float x
)) (* x
2)) 123.45d0
246.9d0
)
3436 (test `(lambda (x) (declare (double-float x
)) (* x
2.0)) 543.21d0
1086.42d0
)
3437 (test `(lambda (x) (declare (double-float x
)) (* x
2.0d0
)) 42.0d0
84.0d0
)))
3439 (with-test (:name
:bug-392203
)
3440 ;; Used to hit an AVER in COMVERT-MV-CALL.
3441 (assert (zerop (funcall
3444 (flet ((k (&rest x
) (declare (ignore x
)) 0))
3445 (multiple-value-call #'k
#'k
))))))))
3447 (with-test (:name
:allocate-closures-failing-aver
)
3448 (let ((f (checked-compile `(lambda ()
3449 (labels ((k (&optional x
) #'k
))))
3450 :allow-style-warnings t
)))
3451 (assert (null (funcall f
)))))
3453 (with-test (:name
:flush-vector-creation
:skipped-on
:interpreter
)
3454 (let ((f (checked-compile `(lambda ()
3458 (ctu:assert-no-consing
(funcall f
))))
3460 (with-test (:name
:array-type-predicates
)
3461 (dolist (et (list* '(integer -
1 200) '(integer -
256 1)
3464 '(double-float 0d0
(1d0))
3465 '(single-float (0s0) (1s0))
3466 '(or (eql 1d0
) (eql 10d0
))
3468 '(complex (member 10 20))
3469 '(complex (member 10d0
20d0
))
3470 '(complex (member 10s0
20s0
))
3471 '(or integer double-float
)
3475 #+sb-unicode
'extended-char
3476 #+sb-unicode
'(eql #\cyrillic_small_letter_yu
)
3477 sb-kernel
::*specialized-array-element-types
*))
3479 (let* ((v (make-array 3 :element-type et
))
3480 (fun (checked-compile
3482 (list (if (typep ,v
'(simple-array ,et
(*)))
3485 (if (typep (elt ,v
0) '(simple-array ,et
(*)))
3488 (assert (equal '(:good
:good
) (funcall fun
)))))))
3490 (with-test (:name
:truncate-float
)
3491 (let ((s (checked-compile `(lambda (x)
3492 (declare (single-float x
))
3494 (d (checked-compile `(lambda (x)
3495 (declare (double-float x
))
3497 (s-inlined (checked-compile
3499 (declare (type (single-float 0.0s0
1.0s0
) x
))
3501 (d-inlined (checked-compile
3503 (declare (type (double-float 0.0d0
1.0d0
) x
))
3505 ;; Check that there is no generic arithmetic
3506 (assert (not (search "GENERIC"
3507 (with-output-to-string (out)
3508 (disassemble s
:stream out
)))))
3509 (assert (not (search "GENERIC"
3510 (with-output-to-string (out)
3511 (disassemble d
:stream out
)))))
3512 ;; Check that we actually inlined the call when we were supposed to.
3513 (assert (not (search "UNARY-TRUNCATE"
3514 (with-output-to-string (out)
3515 (disassemble s-inlined
:stream out
)))))
3516 (assert (not (search "UNARY-TRUNCATE"
3517 (with-output-to-string (out)
3518 (disassemble d-inlined
:stream out
)))))))
3520 (with-test (:name
(make-array :unnamed-dimension-leaf
))
3521 (let ((fun (checked-compile `(lambda (stuff)
3522 (make-array (map 'list
'length stuff
))))))
3523 (assert (equalp #2A
((0 0 0) (0 0 0))
3524 (funcall fun
'((1 2) (1 2 3)))))))
3526 (with-test (:name
:fp-decoding-funs-not-flushable-in-safe-code
)
3527 (dolist (name '(float-sign float-radix float-digits float-precision decode-float
3528 integer-decode-float
))
3529 (let ((fun (checked-compile `(lambda (x)
3530 (declare (optimize safety
))
3538 (error "(~S ~S) did not error"
3544 (when (member name
'(decode-float integer-decode-float
))
3545 (test sb-ext
:single-float-positive-infinity
))))))
3547 (with-test (:name
:sap-ref-16
)
3548 (let* ((fun (checked-compile
3550 (declare (type sb-sys
:system-area-pointer x
)
3551 (type (integer 0 100) y
))
3552 (sb-sys:sap-ref-16 x
(+ 4 y
)))))
3553 (vector (coerce '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
3554 '(simple-array (unsigned-byte 8) (*))))
3555 (sap (sb-sys:vector-sap vector
))
3556 (ret (funcall fun sap
0)))
3557 ;; test for either endianness
3558 (assert (or (= ret
(+ (* 5 256) 4)) (= ret
(+ (* 4 256) 5))))))
3560 (with-test (:name
(compile coerce
:type-warning
))
3561 (dolist (type '(t (unsigned-byte 8) (unsigned-byte 16) (unsigned-byte 32)
3562 (signed-byte 8) (signed-byte 16) (signed-byte 32)))
3563 (let ((fun (checked-compile `(lambda (x)
3564 (declare (type simple-vector x
))
3565 (coerce x
'(vector ,type
))))))
3566 (assert (typep (funcall fun
#(1)) `(simple-array ,type
(*)))))))
3568 (with-test (:name
(compile truncate double-float
))
3569 (let ((fun (checked-compile `(lambda (x)
3570 (multiple-value-bind (q r
)
3571 (truncate (coerce x
'double-float
))
3572 (declare (type unsigned-byte q
)
3573 (type double-float r
))
3575 (assert (equal (funcall fun
1.0d0
) '(1 0.0d0
)))))
3577 (with-test (:name
:set-slot-value-no-warning
)
3578 (let ((notes (nth-value
3579 4 (checked-compile `(lambda (x y
)
3580 (declare (optimize speed safety
))
3581 (setf (slot-value x
'bar
) y
))))))
3582 (assert (= 1 (length notes
)))))
3584 (with-test (:name
(concatenate :string-opt
))
3585 (flet ((test (type grep
)
3586 (let* ((fun (checked-compile `(lambda (a b c d e
)
3587 (concatenate ',type a b c d e
))))
3588 (args '("foo" #(#\.
) "bar" (#\-
) "quux"))
3589 (res (apply fun args
)))
3590 (assert (search grep
(with-output-to-string (out)
3591 (disassemble fun
:stream out
))))
3592 (assert (equal (apply #'concatenate type args
)
3594 (assert (typep res type
)))))
3596 (test 'string
"%CONCATENATE-TO-STRING")
3598 (test 'simple-string
"%CONCATENATE-TO-STRING")
3599 (test 'base-string
"%CONCATENATE-TO-BASE-STRING")
3600 (test 'simple-base-string
"%CONCATENATE-TO-BASE-STRING")))
3602 (with-test (:name
(satisfies :no-local-fun
))
3603 (let ((fun (checked-compile
3605 (labels ((local-not-global-bug (x)
3608 (typep x
'(satisfies local-not-global-bug
))))
3610 (assert (eq 'local-not-global-bug
3613 (undefined-function (c)
3614 (cell-error-name c
)))))))
3616 ;;; Prior to 1.0.32.x, dumping a fasl with a function with a default
3617 ;;; argument that is a complex structure (needing make-load-form
3618 ;;; processing) failed an AVER. The first attempt at a fix caused
3619 ;;; doing the same in-core to break.
3620 (with-test (:name
:bug-310132
)
3621 (checked-compile `(lambda (&optional
(foo #p
"foo/bar")))
3622 :allow-style-warnings t
))
3624 (with-test (:name
:bug-309129
)
3625 (multiple-value-bind (fun failurep warnings
)
3626 (checked-compile `(lambda (v) (values (svref v
0) (vector-pop v
)))
3627 :allow-failure t
:allow-warnings t
)
3629 (assert (= 1 (length warnings
)))
3630 (handler-case (funcall fun
#(1))
3632 ;; we used to put simply VECTOR into EXPECTED-TYPE, rather
3633 ;; than explicitly (AND VECTOR (NOT SIMPLE-ARRAY))
3634 (assert (not (typep (type-error-datum c
) (type-error-expected-type c
)))))
3635 (:no-error
(&rest values
)
3636 (declare (ignore values
))
3637 (error "no error")))))
3639 (with-test (:name
(round :unary
:type-derivation
))
3640 (let ((fun (checked-compile
3642 (multiple-value-bind (h m
) (truncate (abs zone
) 1.0)
3643 (declare (ignore h
))
3644 (round (* 60.0 m
)))))))
3645 (assert (= (funcall fun
0.5) 30))))
3647 (with-test (:name
:bug-525949
)
3648 (let ((fun (checked-compile
3650 (labels ((always-one () 1)
3652 (let ((n (funcall z
)))
3653 (declare (fixnum n
))
3654 (the double-float
(expt n
1.0d0
)))))
3655 (f #'always-one
))))))
3656 (assert (= 1.0d0
(funcall fun
)))))
3658 (with-test (:name
:%array-data-vector-type-derivation
)
3659 (let* ((f (checked-compile
3661 (declare (type (simple-array (unsigned-byte 32) (3 3)) ary
))
3662 (setf (aref ary
0 0) 0))))
3663 (text (with-output-to-string (s)
3664 (disassemble f
:stream s
))))
3665 (assert (not (search "OBJECT-NOT-SIMPLE-ARRAY-UNSIGNED-BYTE-32-ERROR" text
)))))
3667 (with-test (:name
:array-storage-vector-type-derivation
)
3668 (let ((f (checked-compile
3670 (declare (type (simple-array (unsigned-byte 32) (3 3)) ary
))
3671 (ctu:compiler-derived-type
(array-storage-vector ary
))))))
3672 (assert (equal '(simple-array (unsigned-byte 32) (9))
3673 (funcall f
(make-array '(3 3) :element-type
'(unsigned-byte 32)))))))
3675 (with-test (:name
:bug-523612
)
3676 (let ((fun (checked-compile
3677 `(lambda (&key toff
)
3678 (make-array 3 :element-type
'double-float
3680 (if toff
(list toff
0d0
0d0
) (list 0d0
0d0
0d0
)))))))
3681 (assert (equalp (vector 0.0d0
0.0d0
0.0d0
) (funcall fun
:toff nil
)))
3682 (assert (equalp (vector 2.3d0
0.0d0
0.0d0
) (funcall fun
:toff
2.3d0
)))))
3684 (with-test (:name
:bug-309788
)
3685 (let ((fun (checked-compile `(lambda (x)
3686 (declare (optimize speed
))
3688 (typep x
'fixnum env
))))))
3689 (assert (not (ctu:find-named-callees fun
)))))
3691 (with-test (:name
:bug-309124
)
3692 (let ((fun (checked-compile `(lambda (x)
3693 (declare (integer x
))
3694 (declare (optimize speed
))
3695 (cond ((typep x
'fixnum
)
3703 (assert (equal (list "hala" "hip")
3704 (sort (ctu:find-code-constants fun
:type
'string
)
3707 (with-test (:name
:bug-316078
)
3708 (let ((fun (checked-compile
3710 (declare (type (and simple-bit-vector
(satisfies bar
)) x
)
3713 (assert (not (ctu:find-named-callees fun
)))
3714 (assert (= 1 (funcall fun
#*000001)))
3715 (assert (= 0 (funcall fun
#*000010)))))
3717 (with-test (:name
:mult-by-one-in-float-acc-zero
)
3718 (assert (eql 1.0 (funcall (checked-compile
3720 (declare (optimize (sb-c::float-accuracy
0)))
3723 (assert (eql -
1.0 (funcall (checked-compile
3725 (declare (optimize (sb-c::float-accuracy
0)))
3728 (assert (eql 1.0d0
(funcall (checked-compile
3730 (declare (optimize (sb-c::float-accuracy
0)))
3733 (assert (eql -
1.0d0
(funcall (checked-compile
3735 (declare (optimize (sb-c::float-accuracy
0)))
3739 (with-test (:name
:dotimes-non-integer-counter-value
)
3740 (assert-error (dotimes (i 8.6)) type-error
))
3742 (with-test (:name
:bug-454681
)
3743 ;; This used to break due to reference to a dead lambda-var during
3744 ;; inline expansion.
3745 (assert (checked-compile
3747 (multiple-value-bind (iterator+977 getter
+978)
3748 (does-not-exist-but-does-not-matter)
3749 (flet ((iterator+976 ()
3750 (funcall iterator
+977)))
3751 (declare (inline iterator
+976))
3752 (let ((iterator+976 #'iterator
+976))
3753 (funcall iterator
+976)))))
3754 :allow-style-warnings t
)))
3756 (with-test (:name
:complex-float-local-fun-args
)
3757 ;; As of 1.0.27.14, the lambda below failed to compile due to the
3758 ;; compiler attempting to pass unboxed complex floats to Z and the
3759 ;; MOVE-ARG method not expecting the register being used as a
3760 ;; temporary frame pointer. Reported by sykopomp in #lispgames,
3761 ;; reduced test case provided by _3b`.
3762 (checked-compile `(lambda (a)
3764 (declare ((complex double-float
) b c
))
3766 (loop for i below
10 do
3767 (setf a
(z a a
)))))))
3769 (with-test (:name
:bug-309130
)
3771 (let ((warnings (nth-value
3772 2 (checked-compile form
:allow-warnings t
))))
3773 (assert (= 1 (length warnings
))))))
3774 (test `(lambda () (svref (make-array 8 :adjustable t
) 1)))
3776 (declare (optimize (debug 0)))
3777 (declare (type vector x
))
3778 (list (fill-pointer x
) (svref x
1))))
3780 (list (vector-push (svref x
0) x
))))
3782 (list (vector-push-extend (svref x
0) x
))))))
3784 (with-test (:name
:bug-646796
)
3785 (assert (= 42 (funcall (checked-compile
3787 (load-time-value (the (values fixnum
) 42))))))))
3789 (with-test (:name
:bug-654289
)
3790 ;; Test that compile-times don't explode when quoted constants
3792 (labels ((time-n (n)
3793 (gc :full t
) ; Let's not confuse the issue with GC
3794 (let* ((tree (make-tree (expt 10 n
) nil
))
3795 (t0 (get-internal-run-time))
3796 (f (compile nil
`(lambda (x) (eq x
(quote ,tree
)))))
3797 (t1 (get-internal-run-time)))
3798 (assert (funcall f tree
))
3801 (cond ((zerop n
) acc
)
3802 (t (make-tree (1- n
) (cons acc acc
))))))
3803 (let* ((times (loop for i from
0 upto
4
3804 collect
(time-n i
)))
3805 (max-small (reduce #'max times
:end
3))
3806 (max-big (reduce #'max times
:start
3)))
3807 ;; This way is hopefully fairly CPU-performance insensitive.
3808 (unless (> (+ (truncate internal-time-units-per-second
10)
3811 (error "Bad scaling or test? ~S" times
)))))
3813 (with-test (:name
:bug-309063
)
3814 (let ((fun (compile nil
`(lambda (x)
3815 (declare (type (integer 0 0) x
))
3817 (assert (zerop (funcall fun
0)))))
3819 (with-test (:name
:bug-655872
)
3820 (let ((f (compile nil
`(lambda (x)
3821 (declare (optimize (safety 3)))
3822 (aref (locally (declare (optimize (safety 0)))
3823 (coerce x
'(simple-vector 128)))
3825 (long (make-array 100 :element-type
'fixnum
)))
3827 (setf (aref long i
) i
))
3828 ;; 1. COERCE doesn't check the length in unsafe code.
3829 (assert (eql 60 (funcall f long
)))
3830 ;; 2. The compiler doesn't trust the length from COERCE
3833 (funcall f
(list 1 2 3))
3834 (sb-int:invalid-array-index-error
(e)
3835 (assert (eql 60 (type-error-datum e
)))
3836 (assert (equal '(integer 0 (3)) (type-error-expected-type e
)))
3839 (with-test (:name
:bug-655203-regression
)
3840 (let ((fun (compile nil
3844 (&OPTIONAL DUMMY
&REST OTHER
)
3845 (DECLARE (IGNORE OTHER
))
3848 (FUNCALL CONTINUATION
(LIST 1 2)))))))
3849 ;; This used to signal a bogus type-error.
3850 (assert (equal (with-output-to-string (*standard-output
*)
3854 (with-test (:name
:constant-concatenate-compile-time
)
3855 (flet ((make-lambda (n)
3857 (declare (optimize (speed 3) (space 0)))
3858 (concatenate 'string x
,(make-string n
)))))
3859 (let* ((l0 (make-lambda 1))
3860 (l1 (make-lambda 10))
3861 (l2 (make-lambda 100))
3862 (l3 (make-lambda 1000))
3863 (t0 (get-internal-run-time))
3864 (f0 (checked-compile l0
))
3865 (t1 (get-internal-run-time))
3866 (f1 (checked-compile l1
))
3867 (t2 (get-internal-run-time))
3868 (f2 (checked-compile l2
))
3869 (t3 (get-internal-run-time))
3870 (f3 (checked-compile l3
))
3871 (t4 (get-internal-run-time))
3876 (short-avg (/ (+ d0 d1 d2
) 3)))
3877 (assert (and f0 f1 f2 f3
))
3878 (assert (< d3
(* 10 short-avg
))))))
3880 (with-test (:name
:bug-384892
)
3882 '(function (fixnum fixnum
&key
(:k1 boolean
))
3883 (values (member t
) &optional
))
3884 (sb-kernel:%simple-fun-type
3885 (checked-compile `(lambda (x y
&key k1
)
3886 (declare (fixnum x y
))
3887 (declare (boolean k1
))
3888 (declare (ignore x y k1
))
3891 (with-test (:name
:bug-309448
)
3892 ;; Like all tests trying to verify that something doesn't blow up
3893 ;; compile-times this is bound to be a bit brittle, but at least
3894 ;; here we try to establish a decent baseline.
3895 (labels ((time-it (lambda want
&optional times
)
3896 (gc :full t
) ; let's keep GCs coming from other code out...
3897 (let* ((start (get-internal-run-time))
3901 for result
= (checked-compile lambda
)
3902 finally
(return result
))
3903 (loop for result
= (checked-compile lambda
)
3904 do
(incf iterations
)
3905 until
(> (get-internal-run-time) (+ start
10))
3906 finally
(return result
))))
3907 (end (get-internal-run-time))
3908 (got (funcall fun
)))
3909 (unless (eql want got
)
3910 (error "wanted ~S, got ~S" want got
))
3911 (values (- end start
) iterations
)))
3912 (test-it (simple result1 complex result2
)
3913 (multiple-value-bind (time-simple iterations
)
3914 (time-it simple result1
)
3915 (assert (>= (* 10 (1+ time-simple
))
3916 (time-it complex result2 iterations
))))))
3917 ;; This is mostly identical as the next one, but doesn't create
3918 ;; hairy unions of numeric types.
3919 (test-it `(lambda ()
3920 (labels ((bar (baz bim
)
3921 (let ((n (+ baz bim
)))
3922 (* n
(+ n
1) bim
))))
3929 (labels ((bar (baz bim
)
3930 (let ((n (+ baz bim
)))
3931 (* n
(+ n
1) bim
))))
3937 (test-it `(lambda ()
3939 (let ((m (truncate 999 n
)))
3940 (/ (* n m
(1+ m
)) 2))))
3947 (let ((m (truncate 999 n
)))
3948 (/ (* n m
(1+ m
)) 2))))
3954 (with-test (:name
:regression-1.0
.44.34)
3956 `(lambda (z &rest args
)
3957 (declare (dynamic-extent args
))
3958 (flet ((foo (w v
) (list v w
)))
3962 (declare (sb-int:truly-dynamic-extent
#'foo
))
3964 :allow-style-warnings t
))
3966 (with-test (:name
:bug-713626
)
3967 (let ((f (eval '(constantly 42))))
3968 (assert (= 42 (funcall (checked-compile
3969 `(lambda () (funcall ,f
1 2 3))))))))
3971 (with-test (:name
:known-fun-allows-other-keys
)
3972 (funcall (checked-compile
3973 `(lambda () (directory "." :allow-other-keys t
))))
3974 (funcall (checked-compile
3975 `(lambda () (directory "." :bar t
:allow-other-keys t
)))))
3977 (with-test (:name
:bug-551227
)
3978 ;; This function causes constraint analysis to perform a
3979 ;; ref-substitution that alters the A referred to in (G A) at in the
3980 ;; consequent of the IF to refer to be NUMBER, from the
3981 ;; LET-converted inline-expansion of MOD. This leads to attempting
3982 ;; to CLOSE-OVER a variable that simply isn't in scope when it is
3994 :allow-style-warnings t
))
3996 (with-test (:name
:funcall-lambda-inlined
)
3998 (ctu:find-code-constants
3999 (checked-compile `(lambda (x y
)
4000 (+ x
(funcall (lambda (z) z
) y
))))
4003 (with-test (:name
:bug-720382
)
4004 (multiple-value-bind (fun failurep warnings
)
4005 (checked-compile `(lambda (b) ((lambda () b
) 1)) :allow-warnings t
)
4007 (assert (= 1 (length warnings
)))
4008 (assert-error (funcall fun
0))))
4010 (with-test (:name
:multiple-args-to-function
)
4011 (let ((form `(flet ((foo (&optional
(x 13)) x
))
4012 (funcall (function foo
42))))
4013 #+sb-eval
(*evaluator-mode
* :interpret
))
4016 (handler-case (eval form
)
4017 (error () :error
))))
4018 (multiple-value-bind (fun warn fail
)
4019 (compile nil
`(lambda () ,form
))
4020 (assert (and warn fail
))
4022 (handler-case (funcall fun
)
4023 (error () :error
)))))))
4025 ;;; This doesn't test LVAR-FUN-IS directly, but captures it
4026 ;;; pretty accurately anyways.
4027 (with-test (:name
:lvar-fun-is
:skipped-on
:interpreter
)
4029 (lambda (x) (member x x
:test
#'eq
))
4030 (lambda (x) (member x x
:test
'eq
))
4031 (lambda (x) (member x x
:test
#.
#'eq
))))
4032 (assert (equal (list #'sb-kernel
:%member-eq
)
4033 (ctu:find-named-callees fun
))))
4036 (declare (notinline eq
))
4037 (member x x
:test
#'eq
))
4039 (declare (notinline eq
))
4040 (member x x
:test
'eq
))
4042 (declare (notinline eq
))
4043 (member x x
:test
#.
#'eq
))))
4044 (assert (member #'sb-kernel
:%member-test
4045 (ctu:find-named-callees fun
)))))
4047 (with-test (:name
:delete-to-delq-opt
:skipped-on
:interpreter
)
4048 (dolist (fun (list (lambda (x y
)
4050 (delete x y
:test
#'eq
))
4052 (declare (fixnum x
) (list y
))
4055 (declare (symbol x
) (list y
))
4056 (delete x y
:test
#'eql
))))
4057 (assert (equal (list #'sb-int
:delq
)
4058 (ctu:find-named-callees fun
)))))
4060 (with-test (:name
:bug-767959
)
4061 ;; This used to signal an error.
4062 (compile nil
`(lambda ()
4063 (declare (optimize sb-c
:store-coverage-data
))
4066 '((:ordinary . ordinary-lambda-list
))))))
4068 ;; This test failed formerly because the source transform of TYPEP would be
4069 ;; disabled when storing coverage data, thus giving no semantics to
4070 ;; expressions such as (TYPEP x 'INTEGER). The compiler could therefore not
4071 ;; prove that the else clause of the IF is unreachable - which it must be
4072 ;; since X is asserted to be fixnum. The conflicting requirement on X
4073 ;; that it be acceptable to LENGTH signaled a full warning.
4074 ;; Nobody on sbcl-devel could remember why the source transform was disabled,
4075 ;; but nobody disagreed with undoing the disabling.
4076 (with-test (:name
:sb-cover-and-typep
)
4077 (multiple-value-bind (fun warnings-p failure-p
)
4078 (compile nil
'(lambda (x)
4079 (declare (fixnum x
) (optimize sb-c
:store-coverage-data
))
4080 (if (typep x
'integer
) x
(length x
))))
4081 (assert (and fun
(not warnings-p
) (not failure-p
)))))
4083 (with-test (:name
:member-on-long-constant-list
)
4084 ;; This used to blow stack with a sufficiently long list.
4085 (let ((cycle (list t
)))
4087 (compile nil
`(lambda (x)
4088 (member x
',cycle
)))))
4090 (with-test (:name
:bug-722734
)
4096 (list unbound-variable-1 unbound-variable-2
)))))))
4098 (with-test (:name
:bug-771673
)
4099 (assert (equal `(the foo bar
) (macroexpand `(truly-the foo bar
))))
4100 ;; Make sure the compiler doesn't use THE, and check that setf-expansions
4102 (let ((f (compile nil
`(lambda (x y
)
4103 (setf (truly-the fixnum
(car x
)) y
)))))
4104 (let* ((cell (cons t t
)))
4105 (funcall f cell
:ok
)
4106 (assert (equal '(:ok . t
) cell
)))))
4108 (with-test (:name
(:bug-793771
+))
4109 (let ((f (compile nil
`(lambda (x y
)
4110 (declare (type (single-float 2.0) x
)
4111 (type (single-float (0.0
)) y
))
4113 (assert (equal `(function ((single-float 2.0) (single-float (0.0
)))
4114 (values (single-float 2.0) &optional
))
4115 (sb-kernel:%simple-fun-type f
)))))
4117 (with-test (:name
(:bug-793771 -
))
4118 (let ((f (compile nil
`(lambda (x y
)
4119 (declare (type (single-float * 2.0) x
)
4120 (type (single-float (0.0
)) y
))
4122 (assert (equal `(function ((single-float * 2.0) (single-float (0.0
)))
4123 (values (single-float * 2.0) &optional
))
4124 (sb-kernel:%simple-fun-type f
)))))
4126 (with-test (:name
(:bug-793771
*))
4127 (let ((f (checked-compile
4129 (declare (type (single-float (0.0
)) x
))
4131 (assert (equal `(function ((single-float (0.0
)))
4132 (values (single-float 0.0) &optional
))
4133 (sb-kernel:%simple-fun-type f
)))))
4135 (with-test (:name
(:bug-793771
/))
4136 (let ((f (checked-compile
4138 (declare (type (single-float (0.0
)) x
))
4140 (assert (equal `(function ((single-float (0.0
)))
4141 (values (single-float 0.0) &optional
))
4142 (sb-kernel:%simple-fun-type f
)))))
4144 (with-test (:name
(:bug-486812 single-float
))
4145 (compile nil
`(lambda ()
4146 (sb-kernel:make-single-float -
1))))
4148 (with-test (:name
(:bug-486812 double-float
))
4149 (compile nil
`(lambda ()
4150 (sb-kernel:make-double-float -
1 0))))
4152 (with-test (:name
:bug-729765
)
4153 (compile nil
`(lambda (a b
)
4154 (declare ((integer 1 1) a
)
4157 (lambda () (< b a
)))))
4159 ;; Actually tests the assembly of RIP-relative operands to comparison
4160 ;; functions (one of the few x86 instructions that have extra bytes
4161 ;; *after* the mem operand's effective address, resulting in a wrong
4163 (with-test (:name
:cmpps
)
4164 (let ((foo (compile nil
`(lambda (x)
4165 (= #C
(2.0
3.0) (the (complex single-float
) x
))))))
4166 (assert (funcall foo
#C
(2.0
3.0)))
4167 (assert (not (funcall foo
#C
(1.0
2.0))))))
4169 (with-test (:name
:cmppd
)
4170 (let ((foo (compile nil
`(lambda (x)
4171 (= #C
(2d0 3d0
) (the (complex double-float
) x
))))))
4172 (assert (funcall foo
#C
(2d0 3d0
)))
4173 (assert (not (funcall foo
#C
(1d0 2d0
))))))
4175 (with-test (:name
:lvar-externally-checkable-type-nil
)
4176 ;; Used to signal a BUG during compilation.
4177 (let ((fun (compile nil
`(lambda (a) (parse-integer "12321321" (the (member :start
) a
) 1)))))
4178 (multiple-value-bind (i p
) (funcall fun
:start
)
4179 (assert (= 2321321 i
))
4181 (multiple-value-bind (i e
) (ignore-errors (funcall fun
:end
))
4183 (assert (typep e
'type-error
)))))
4185 (with-test (:name
:simple-type-error-in-bound-propagation-a
)
4186 (compile nil
`(lambda (i)
4187 (declare (unsigned-byte i
))
4188 (expt 10 (expt 7 (- 2 i
))))))
4190 (with-test (:name
:simple-type-error-in-bound-propagation-b
)
4191 (assert (equal `(FUNCTION (UNSIGNED-BYTE)
4192 (VALUES (SINGLE-FLOAT -
1F0
1F0
) &OPTIONAL
))
4193 (sb-kernel:%simple-fun-type
4194 (compile nil
`(lambda (i)
4195 (declare (unsigned-byte i
))
4196 (cos (expt 10 (+ 4096 i
)))))))))
4198 (with-test (:name
:fixed-%more-arg-values
)
4199 (let ((fun (compile nil
`(lambda (&rest rest
)
4200 (declare (optimize (safety 0)))
4201 (apply #'cons rest
)))))
4202 (assert (equal '(car . cdr
) (funcall fun
'car
'cdr
)))))
4204 (with-test (:name
:bug-826970
)
4205 (let ((fun (compile nil
`(lambda (a b c
)
4206 (declare (type (member -
2 1) b
))
4207 (array-in-bounds-p a
4 b c
)))))
4208 (assert (funcall fun
(make-array '(5 2 2)) 1 1))))
4210 (with-test (:name
:bug-826971
)
4212 (fun (compile nil
`(lambda (p1 p2
)
4213 (schar (the (eql ,foo
) p1
) p2
)))))
4214 (assert (eql #\f (funcall fun foo
0)))))
4216 (with-test (:name
:bug-738464
)
4217 (multiple-value-bind (fun warn fail
)
4218 (compile nil
`(lambda ()
4220 (declare (ftype non-function-type foo
))
4222 (assert (eql 42 (funcall fun
)))
4223 (assert (and warn
(not fail
)))))
4225 (with-test (:name
:bug-832005
)
4226 (let ((fun (compile nil
`(lambda (x)
4227 (declare (type (complex single-float
) x
))
4228 (+ #C
(0.0
1.0) x
)))))
4229 (assert (= (funcall fun
#C
(1.0
2.0))
4232 ;; A refactoring 1.0.12.18 caused lossy computation of primitive
4233 ;; types for member types.
4234 (with-test (:name
:member-type-primitive-type
)
4235 (let ((fun (compile nil
`(lambda (p1 p2 p3
)
4237 (the (member #c
(1.2d0
1d0
)) p2
)
4238 (the (eql #c
(1.0
1.0)) p3
))))))
4239 (assert (eql (funcall fun
1 #c
(1.2d0
1d0
) #c
(1.0
1.0))
4242 ;; Fall-through jump elimination made control flow fall through to trampolines.
4243 ;; Reported by Eric Marsden on sbcl-devel@ 2011.10.26, with a test case
4244 ;; reproduced below (triggered a corruption warning and a memory fault).
4245 (with-test (:name
:bug-883500
)
4246 (funcall (compile nil
`(lambda (a)
4247 (declare (type (integer -
50 50) a
))
4248 (declare (optimize (speed 0)))
4249 (mod (mod a
(min -
5 a
)) 5)))
4252 ;; Test for literals too large for the ISA (e.g. (SIGNED-BYTE 13) on SPARC).
4254 (with-test (:name
:bug-883519
)
4255 (compile nil
`(lambda (x)
4256 (declare (type character x
))
4257 (eql x
#\U0010FFFF
))))
4259 ;; Wide fixnum platforms had buggy address computation in atomic-incf/aref
4260 (with-test (:name
:bug-887220
)
4261 (let ((incfer (compile
4263 `(lambda (vector index
)
4264 (declare (type (simple-array sb-ext
:word
(4))
4266 (type (mod 4) index
))
4267 (sb-ext:atomic-incf
(aref vector index
) 1)
4269 (assert (equalp (funcall incfer
4270 (make-array 4 :element-type
'sb-ext
:word
4275 (with-test (:name
:catch-interferes-with-debug-names
)
4281 (throw 'out
(lambda () t
))))
4283 (assert (equal '(lambda () :in foo
) (sb-kernel:%fun-name fun
)))))
4285 (with-test (:name
:interval-div-signed-zero
)
4286 (let ((fun (compile nil
4288 (declare (type (member 0 -
272413371076) a
))
4289 (ffloor (the number a
) -
63243.127451934015d0
)))))
4290 (multiple-value-bind (q r
) (funcall fun
0)
4291 (assert (eql -
0d0 q
))
4292 (assert (eql 0d0 r
)))))
4294 (with-test (:name
:non-constant-keyword-typecheck
)
4295 (let ((fun (compile nil
4297 (declare (type keyword p3
))
4298 (tree-equal p1
(cons 1 2) (the (member :test
) p3
) p4
)))))
4299 (assert (funcall fun
(cons 1.0 2.0) :test
'=))))
4301 (with-test (:name
:truncate-wild-values
)
4302 (multiple-value-bind (q r
)
4303 (handler-bind ((warning #'error
))
4304 (let ((sb-c::*check-consistency
* t
))
4305 (funcall (compile nil
4307 (declare (type (member 1d0
2d0
) a
))
4308 (block return-value-tag
4311 (catch 'debug-catch-tag
4312 (return-from return-value-tag
4313 (progn (truncate a
)))))))))
4316 (assert (eql 0d0 r
))))
4318 (with-test (:name
:boxed-fp-constant-for-full-call
)
4319 (let ((fun (compile nil
4321 (declare (double-float x
))
4322 (unknown-fun 1.0d0
(+ 1.0d0 x
))))))
4323 (assert (equal '(1.0d0
) (ctu:find-code-constants fun
:type
'double-float
)))))
4325 (with-test (:name
:only-one-boxed-constant-for-multiple-uses
)
4326 (let* ((big (1+ most-positive-fixnum
))
4329 (unknown-fun ,big
(+ ,big x
))))))
4330 (assert (= 1 (length (ctu:find-code-constants fun
:type
`(eql ,big
)))))))
4332 (with-test (:name
:fixnum
+float-coerces-fixnum
4334 (let ((fun (compile nil
4339 (assert (not (ctu:find-named-callees fun
)))
4340 (assert (not (search "GENERIC"
4341 (with-output-to-string (s)
4342 (disassemble fun
:stream s
)))))))
4344 (with-test (:name
:bug-803508
)
4345 (compile nil
`(lambda ()
4348 (declare (dynamic-extent bar
))
4351 (with-test (:name
:bug-803508-b
)
4352 (compile nil
`(lambda ()
4355 (declare (dynamic-extent bar
))
4358 (with-test (:name
:bug-803508-c
)
4359 (compile nil
`(lambda ()
4361 (lambda (bar &optional quux
)
4362 (declare (dynamic-extent bar quux
))
4365 (with-test (:name
:cprop-with-constant-but-assigned-to-closure-variable
)
4366 (compile nil
`(lambda (b c d
)
4367 (declare (type (integer -
20545789 207590862) c
))
4368 (declare (type (integer -
1 -
1) d
))
4369 (let ((i (unwind-protect 32 (shiftf d -
1))))
4370 (or (if (= d c
) 2 (= 3 b
)) 4)))))
4372 (with-test (:name
:bug-913232
4373 :fails-on
:interpreter
) ; no idea why it fails randomly
4374 (compile nil
`(lambda (x)
4375 (declare (optimize speed
)
4376 (type (or (and (or (integer -
100 -
50)
4377 (integer 100 200)) (satisfies foo
))
4378 (and (or (integer 0 10) (integer 20 30)) a
)) x
))
4380 (compile nil
`(lambda (x)
4381 (declare (optimize speed
)
4382 (type (and fixnum a
) x
))
4385 (with-test (:name
:bug-959687
)
4386 (multiple-value-bind (fun warn fail
)
4387 (compile nil
`(lambda (x)
4393 (assert (and warn fail
))
4394 (assert (not (ignore-errors (funcall fun t
)))))
4395 (multiple-value-bind (fun warn fail
)
4396 (compile nil
`(lambda (x)
4402 (assert (and warn fail
))
4403 (assert (not (ignore-errors (funcall fun t
))))))
4405 (with-test (:name
:bug-924276
)
4406 (assert (eq :style-warning
4408 (compile nil
`(lambda (a)
4409 (cons a
(symbol-macrolet ((b 1))
4410 (declare (ignorable a
))
4415 (with-test (:name
:bug-974406
)
4416 (let ((fun32 (compile nil
`(lambda (x)
4417 (declare (optimize speed
(safety 0)))
4418 (declare (type (integer 53 86) x
))
4419 (logand (+ x
1032791128) 11007078467))))
4420 (fun64 (compile nil
`(lambda (x)
4421 (declare (optimize speed
(safety 0)))
4422 (declare (type (integer 53 86) x
))
4423 (logand (+ x
1152921504606846975)
4424 38046409652025950207)))))
4425 (assert (= (funcall fun32
61) 268574721))
4426 (assert (= (funcall fun64
61) 60)))
4428 (do ((width 5 (1+ width
)))
4431 (let ((fun (compile nil
`(lambda (x)
4432 (declare (optimize speed
(safety 0)))
4433 (declare (type (integer 1 16) x
))
4435 (+ x
,(1- (ash 1 width
)))
4436 ,(logior (ash 1 (+ width
1 extra
))
4437 (1- (ash 1 width
))))))))
4438 (unless (= (funcall fun
16) (logand 15 (1- (ash 1 width
))))
4439 (push (cons width extra
) result
)))))
4440 (assert (null result
))))
4442 ;; On x86-64 MOVE-IMMEDIATE of fixnum values into memory either directly
4443 ;; uses a MOV into memory or goes through a temporary register if the
4444 ;; value is larger than a certain number of bits. Check that it respects
4445 ;; the limits of immediate arguments to the MOV instruction (if not, the
4446 ;; assembler will fail an assertion) and doesn't have sign-extension
4447 ;; problems. (The test passes fixnum constants through the MOVE VOP
4448 ;; which calls MOVE-IMMEDIATE.)
4449 (with-test (:name
:constant-fixnum-move
)
4450 (let ((f (compile nil
`(lambda (g)
4452 ;; The first three args are
4453 ;; uninteresting as they are
4454 ;; passed in registers.
4456 ,@(loop for i from
27 to
32
4457 collect
(expt 2 i
)))))))
4458 (assert (every #'plusp
(funcall f
#'list
)))))
4460 (with-test (:name
(:malformed-ignore
:lp-1000239
) :skipped-on
:interpreter
)
4462 (eval '(lambda () (declare (ignore (function . a
)))))
4463 sb-int
:simple-program-error
)
4465 (eval '(lambda () (declare (ignore (function a b
)))))
4466 sb-int
:simple-program-error
)
4468 (eval '(lambda () (declare (ignore (function)))))
4469 sb-int
:simple-program-error
)
4471 (eval '(lambda () (declare (ignore (a)))))
4472 sb-int
:simple-program-error
)
4474 (eval '(lambda () (declare (ignorable (a b
)))))
4475 sb-int
:simple-program-error
))
4477 (with-test (:name
:malformed-type-declaraions
)
4478 (compile nil
'(lambda (a) (declare (type (integer 1 2 .
3) a
)))))
4480 (with-test (:name
:compiled-program-error-escaped-source
)
4483 (funcall (compile nil
`(lambda () (lambda ("foo")))))
4484 (sb-int:compiled-program-error
(e)
4485 (let ((source (read-from-string (sb-kernel::program-error-source e
))))
4486 (equal source
'#'(lambda ("foo"))))))))
4488 (with-test (:name
:escape-analysis-for-nlxs
:skipped-on
:interpreter
)
4489 (flet ((test (check lambda
&rest args
)
4490 (let* ((cell-note nil
)
4491 (fun (handler-bind ((compiler-note
4494 "Allocating a value-cell at runtime for"
4495 (princ-to-string note
))
4496 (setf cell-note t
)))))
4497 (compile nil lambda
))))
4498 (assert (eql check cell-note
))
4503 (dolist (arg args nil
)
4504 (setf fun
(funcall fun arg
)))
4505 (sb-int:simple-control-error
(e)
4507 (simple-condition-format-control e
)
4508 "attempt to RETURN-FROM a block or GO to a tag that no longer exists")
4510 (ctu:assert-no-consing
(apply fun args
))))))
4511 (test nil
`(lambda (x)
4512 (declare (optimize speed
))
4514 (flet ((ex () (return-from out
'out
!)))
4516 (cons (or (car x
) (ex)))
4518 (test t
`(lambda (x)
4519 (declare (optimize speed
))
4522 (flet ((oops () (return-from nasty t
)))
4524 (test t
`(lambda (r)
4525 (declare (optimize speed
))
4527 (flet ((ex () (return-from out r
)))
4530 (cons (or (car x
) (ex)))
4532 (test t
`(lambda (x)
4533 (declare (optimize speed
))
4535 (flet ((meh () (return-from eh
'meh
)))
4538 (cons (or (car x
) (meh)))
4540 (funcall (eh x
)))) t t
)))
4542 (with-test (:name
(:bug-1050768
:symptom
))
4543 ;; Used to signal an error.
4545 `(lambda (string position
)
4546 (char string position
)
4547 (array-in-bounds-p string
(1+ position
)))))
4549 (with-test (:name
(:bug-1050768
:cause
))
4550 (let ((types `((string string
)
4551 ((or (simple-array character
24) (vector t
24))
4552 (or (simple-array character
24) (vector t
))))))
4553 (dolist (pair types
)
4554 (destructuring-bind (orig conservative
) pair
4555 (assert sb-c
::(type= (specifier-type cl-user
::conservative
)
4556 (conservative-type (specifier-type cl-user
::orig
))))))))
4558 (with-test (:name
(:smodular64
:wrong-width
))
4559 (let ((fun (compile nil
4561 (declare (type (signed-byte 64) x
))
4562 (sb-c::mask-signed-field
64 (- x
7033717698976965573))))))
4563 (assert (= (funcall fun
10038) -
7033717698976955535))))
4565 (with-test (:name
(:smodular32
:wrong-width
))
4566 (let ((fun (compile nil
'(lambda (x)
4567 (declare (type (signed-byte 31) x
))
4568 (sb-c::mask-signed-field
31 (- x
1055131947))))))
4569 (assert (= (funcall fun
10038) -
1055121909))))
4571 (with-test (:name
:first-open-coded
)
4572 (let ((fun (compile nil
`(lambda (x) (first x
)))))
4573 (assert (not (ctu:find-named-callees fun
)))))
4575 (with-test (:name
:second-open-coded
)
4576 (let ((fun (compile nil
`(lambda (x) (second x
)))))
4577 (assert (not (ctu:find-named-callees fun
)))))
4579 (with-test (:name
:svref-of-symbol-macro
)
4580 (compile nil
`(lambda (x)
4581 (symbol-macrolet ((sv x
))
4582 (values (svref sv
0) (setf (svref sv
0) 99))))))
4584 ;; The compiler used to update the receiving LVAR's type too
4585 ;; aggressively when converting a large constant to a smaller
4586 ;; (potentially signed) one, causing other branches to be
4587 ;; inferred as dead.
4588 (with-test (:name
:modular-cut-constant-to-width
)
4589 (let ((test (compile nil
4594 ((2 2 0 -
2 -
1 2) 9223372036854775803)
4596 (assert (= (funcall test -
10470605025) 26))))
4598 (with-test (:name
:append-type-derivation
)
4600 '((lambda () (append 10)) (integer 10 10)
4601 (lambda () (append nil
10)) (integer 10 10)
4602 (lambda (x) (append x
10)) (or (integer 10 10) cons
)
4603 (lambda (x) (append x
(cons 1 2))) cons
4604 (lambda (x y
) (append x
(cons 1 2) y
)) cons
4605 (lambda (x y
) (nconc x
(the list y
) x
)) t
4606 (lambda (x y
) (nconc (the atom x
) y
)) t
4607 (lambda (x y
) (nconc (the (or null
(eql 10)) x
) y
)) t
4608 (lambda (x y
) (nconc (the (or cons vector
) x
) y
)) cons
4609 (lambda (x y
) (nconc (the sequence x
) y
)) t
4610 (lambda (x y
) (print (length y
)) (append x y
)) sequence
4611 (lambda (x y
) (print (length y
)) (append x y
)) sequence
4612 (lambda (x y
) (append (the (member (a) (b)) x
) y
)) cons
4613 (lambda (x y
) (append (the (member (a) (b) c
) x
) y
)) cons
4614 (lambda (x y
) (append (the (member (a) (b) nil
) x
) y
)) t
)))
4615 (loop for
(function result-type
) on test-cases by
#'cddr
4616 do
(assert (sb-kernel:type
= (sb-kernel:specifier-type
4617 (car (cdaddr (sb-kernel:%simple-fun-type
4618 (compile nil function
)))))
4619 (sb-kernel:specifier-type result-type
))))))
4621 (with-test (:name
:bug-504121
)
4622 (compile nil
`(lambda (s)
4623 (let ((p1 #'upper-case-p
))
4627 (let ((p2 #'(lambda (char) (upper-case-p char
))))
4630 (with-test (:name
(:bug-504121
:optional-missing
))
4631 (compile nil
`(lambda (s)
4632 (let ((p1 #'upper-case-p
))
4634 (lambda (g &optional x
)
4636 (let ((p2 #'(lambda (char) (upper-case-p char
))))
4639 (with-test (:name
(:bug-504121
:optional-superfluous
))
4640 (compile nil
`(lambda (s)
4641 (let ((p1 #'upper-case-p
))
4643 (lambda (g &optional x
)
4646 (let ((p2 #'(lambda (char) (upper-case-p char
))))
4649 (with-test (:name
(:bug-504121
:key-odd
))
4650 (compile nil
`(lambda (s)
4651 (let ((p1 #'upper-case-p
))
4656 (let ((p2 #'(lambda (char) (upper-case-p char
))))
4659 (with-test (:name
(:bug-504121
:key-unknown
))
4660 (compile nil
`(lambda (s)
4661 (let ((p1 #'upper-case-p
))
4666 (let ((p2 #'(lambda (char) (upper-case-p char
))))
4669 (with-test (:name
:bug-1181684
)
4670 (compile nil
`(lambda ()
4671 (let ((hash #xD13CCD13
))
4672 (setf hash
(logand most-positive-word
4675 (with-test (:name
(:local-
&optional-recursive-inline
:bug-1180992
))
4678 (labels ((called (&optional a
))
4679 (recursed (&optional b
)
4682 (declare (inline recursed called
))
4685 (with-test (:name
:constant-fold-logtest
)
4686 (assert (equal (sb-kernel:%simple-fun-type
4687 (compile nil
`(lambda (x)
4688 (declare (type (mod 1024) x
)
4691 '(function ((unsigned-byte 10)) (values null
&optional
)))))
4693 ;; type mismatches on LVARs with multiple potential sources used to
4694 ;; be reported as mismatches with the value NIL. Make sure we get
4695 ;; a warning, but that it doesn't complain about a constant NIL ...
4697 (with-test (:name
(:multiple-use-lvar-interpreted-as-NIL
:cast
))
4699 (handler-bind ((sb-int:type-warning
4702 (not (search "Constant "
4703 (simple-condition-format-control
4706 (compile nil
`(lambda (x y z
)
4707 (declare (type fixnum y z
))
4708 (aref (if x y z
) 0))))
4709 (error "Where's my warning?")))
4711 (with-test (:name
(:multiple-use-lvar-interpreted-as-NIL catch
))
4713 (handler-bind ((style-warning
4718 (simple-condition-format-arguments c
))))
4720 (compile nil
`(lambda (x y z f
)
4721 (declare (type fixnum y z
))
4722 (catch (if x y z
) (funcall f
)))))
4723 (error "Where's my style-warning?")))
4725 ;; Smoke test for rightward shifts
4726 (with-test (:name
(:ash
/right-signed
))
4727 (let* ((f (compile nil
`(lambda (x y
)
4728 (declare (type (mod ,(* 2 sb-vm
:n-word-bits
)) y
)
4729 (type sb-vm
:signed-word x
)
4732 (max (ash most-positive-word -
1))
4735 (assert (= (ash x
(- y
))
4738 (dotimes (y (* 2 sb-vm
:n-word-bits
))
4742 (test (+ min x
) y
))))))
4744 (with-test (:name
(:ash
/right-unsigned
))
4745 (let ((f (compile nil
`(lambda (x y
)
4746 (declare (type (mod ,(* 2 sb-vm
:n-word-bits
)) y
)
4750 (max most-positive-word
))
4752 (assert (= (ash x
(- y
))
4755 (dotimes (y (* 2 sb-vm
:n-word-bits
))
4757 (test (- max x
) y
))))))
4759 (with-test (:name
(:ash
/right-fixnum
))
4760 (let ((f (compile nil
`(lambda (x y
)
4761 (declare (type (mod ,(* 2 sb-vm
:n-word-bits
)) y
)
4766 (assert (= (ash x
(- y
))
4769 (dotimes (y (* 2 sb-vm
:n-word-bits
))
4772 (test (- most-positive-fixnum x
) y
)
4773 (test (+ most-negative-fixnum x
) y
))))))
4776 (with-test (:name
:fold-index-addressing-positive-offset
)
4777 (let ((f (compile nil
`(lambda (i)
4778 (if (typep i
'(integer -
31 31))
4779 (aref #.
(make-array 63) (+ i
31))
4783 ;; 5d3a728 broke something like this in CL-PPCRE
4784 (with-test (:name
:fold-index-addressing-potentially-negative-index
)
4785 (compile nil
`(lambda (index vector
)
4786 (declare (optimize speed
(safety 0))
4787 ((simple-array character
(*)) vector
)
4788 ((unsigned-byte 24) index
))
4789 (aref vector
(1+ (mod index
(1- (length vector
))))))))
4791 (with-test (:name
:constant-fold-ash
/right-fixnum
)
4792 (compile nil
`(lambda (a b
)
4793 (declare (type fixnum a
)
4794 (type (integer * -
84) b
))
4797 (with-test (:name
:constant-fold-ash
/right-word
)
4798 (compile nil
`(lambda (a b
)
4799 (declare (type word a
)
4800 (type (integer * -
84) b
))
4803 (with-test (:name
:nconc-derive-type
)
4804 (let ((function (compile nil
`(lambda (x y
)
4805 (declare (type (or cons fixnum
) x
))
4807 (assert (equal (sb-kernel:%simple-fun-type function
)
4808 '(function ((or cons fixnum
) t
) (values cons
&optional
))))))
4810 ;; make sure that all data-vector-ref-with-offset VOPs are either
4811 ;; specialised on a 0 offset or accept signed indices
4812 (with-test (:name
:data-vector-ref-with-offset-signed-index
)
4813 (let ((dvr (find-symbol "DATA-VECTOR-REF-WITH-OFFSET" "SB-KERNEL")))
4817 (loop for info in
(sb-c::fun-info-templates
4818 (sb-c::fun-info-or-lose dvr
))
4819 for
(nil second-arg third-arg
) = (sb-c::vop-info-arg-types info
)
4820 unless
(or (typep second-arg
'(cons (eql :constant
)))
4821 (find '(integer 0 0) third-arg
:test
'equal
)
4823 `(:or
,(sb-c::primitive-type-or-lose
4824 'sb-vm
::positive-fixnum
)
4825 ,(sb-c::primitive-type-or-lose
4829 (with-test (:name
:data-vector-set-with-offset-signed-index
)
4830 (let ((dvr (find-symbol "DATA-VECTOR-SET-WITH-OFFSET" "SB-KERNEL")))
4834 (loop for info in
(sb-c::fun-info-templates
4835 (sb-c::fun-info-or-lose dvr
))
4836 for
(nil second-arg third-arg
) = (sb-c::vop-info-arg-types info
)
4837 unless
(or (typep second-arg
'(cons (eql :constant
)))
4838 (find '(integer 0 0) third-arg
:test
'equal
)
4840 `(:or
,(sb-c::primitive-type-or-lose
4841 'sb-vm
::positive-fixnum
)
4842 ,(sb-c::primitive-type-or-lose
4846 (with-test (:name
:maybe-inline-ref-to-dead-lambda
)
4847 (compile nil
`(lambda (string)
4848 (declare (optimize speed
(space 0)))
4849 (cond ((every #'digit-char-p string
)
4855 ;; the x87 backend used to sometimes signal FP errors during boxing,
4856 ;; because converting between double and single float values was a
4857 ;; noop (fixed), and no doubt many remaining issues. We now store
4858 ;; the value outside pseudo-atomic, so any SIGFPE should be handled
4861 ;; When it fails, this test lands into ldb.
4862 (with-test (:name
:no-overflow-during-allocation
)
4863 (handler-case (eval '(cosh 90))
4864 (floating-point-overflow ()
4867 ;; unbounded integer types could break integer arithmetic.
4868 (with-test (:name
:bug-1199127
)
4869 (compile nil
`(lambda (b)
4870 (declare (type (integer -
1225923945345 -
832450738898) b
))
4871 (declare (optimize (speed 3) (space 3) (safety 2)
4872 (debug 0) (compilation-speed 1)))
4873 (loop for lv1 below
3
4876 (ash b
(min 25 lv1
))
4880 ;; non-trivial modular arithmetic operations would evaluate to wider results
4881 ;; than expected, and never be cut to the right final bitwidth.
4882 (with-test (:name
:bug-1199428-1
)
4883 (let ((f1 (compile nil
`(lambda (a c
)
4884 (declare (type (integer -
2 1217810089) a
))
4885 (declare (type (integer -
6895591104928 -
561736648588) c
))
4886 (declare (optimize (speed 2) (space 0) (safety 2) (debug 0)
4887 (compilation-speed 3)))
4890 (loop for lv2 below
1 count t
))))))
4891 (f2 (compile nil
`(lambda (a c
)
4892 (declare (notinline -
+ gcd logandc1
))
4893 (declare (optimize (speed 1) (space 1) (safety 0) (debug 1)
4894 (compilation-speed 3)))
4897 (loop for lv2 below
1 count t
)))))))
4900 (assert (eql (funcall f1 a c
)
4901 (funcall f2 a c
))))))
4903 (with-test (:name
:bug-1199428-2
)
4904 (let ((f1 (compile nil
`(lambda (a b
)
4905 (declare (type (integer -
1869232508 -
6939151) a
))
4906 (declare (type (integer -
11466348357 -
2645644006) b
))
4907 (declare (optimize (speed 1) (space 0) (safety 2) (debug 2)
4908 (compilation-speed 2)))
4909 (logand (lognand a -
6) (* b -
502823994)))))
4910 (f2 (compile nil
`(lambda (a b
)
4911 (logand (lognand a -
6) (* b -
502823994))))))
4912 (let ((a -
1491588365)
4914 (assert (eql (funcall f1 a b
)
4915 (funcall f2 a b
))))))
4917 ;; win32 is very specific about the order in which catch blocks
4918 ;; must be allocated on the stack
4919 (with-test (:name
:bug-1072739
)
4920 (let ((f (compile nil
4924 (WITH-OUTPUT-TO-STRING (G13908)
4927 (DECLARE (OPTIMIZE (SB-EXT:INHIBIT-WARNINGS
3)))
4929 (WITH-OUTPUT-TO-STRING (G13909) (PRINC %A%B% G13909
) G13909
)
4930 (UNBOUND-VARIABLE NIL
4932 (WITH-OUTPUT-TO-STRING (G13914)
4933 (PRINC %A%B% G13914
)
4936 (UNBOUND-VARIABLE NIL
4938 (WITH-OUTPUT-TO-STRING (G13913)
4942 (UNBOUND-VARIABLE NIL
4944 (WITH-OUTPUT-TO-STRING (G13912)
4948 (UNBOUND-VARIABLE NIL
4950 (WITH-OUTPUT-TO-STRING (G13911)
4952 (PRINC "%b%" G13911
)
4954 (UNBOUND-VARIABLE NIL
4956 (WITH-OUTPUT-TO-STRING (G13910)
4958 (PRINC "a%b%" G13910
)
4960 (UNBOUND-VARIABLE NIL
4961 (ERROR "Interpolation error in \"%a%b%\"
4965 (assert (funcall f
))))
4967 (with-test (:name
:equal-equalp-transforms
)
4969 (bit-vector #*11001100)
4970 (values `(nil 1 2 "test"
4971 ;; Floats duplicated here to ensure we get newly created instances
4972 (read-from-string "1.1") (read-from-string "1.2d0")
4973 (read-from-string "1.1") (read-from-string "1.2d0")
4974 1.1 1.2d0
'("foo" "bar" "test")
4975 #(1 2 3 4) #*101010 (make-broadcast-stream) #p
"/tmp/file"
4976 ,s
(copy-seq ,s
) ,bit-vector
(copy-seq ,bit-vector
)
4977 ,(make-hash-table) #\a #\b #\A
#\C
4978 ,(make-random-state) 1/2 2/3)))
4979 ;; Test all permutations of different types
4986 (and (eq (funcall (compile nil
`(lambda (x y
)
4987 (equal (the ,(type-of x
) x
)
4988 (the ,(type-of y
) y
))))
4991 (eq (funcall (compile nil
`(lambda (x y
)
4992 (equalp (the ,(type-of x
) x
)
4993 (the ,(type-of y
) y
))))
5000 (equal (the (cons (or simple-bit-vector simple-base-string
))
5002 (the (cons (or (and bit-vector
(not simple-array
))
5003 (simple-array character
(*))))
5005 (list (string 'list
))
5011 (equalp (the (cons (or simple-bit-vector simple-base-string
))
5013 (the (cons (or (and bit-vector
(not simple-array
))
5014 (simple-array character
(*))))
5016 (list (string 'list
))
5019 (with-test (:name
(restart-case optimize speed compiler-note
)
5020 ;; Cannot-DX note crashes test driver unless we have this:
5021 :skipped-on
'(not :stack-allocatable-fixed-objects
))
5022 (handler-bind ((compiler-note #'error
))
5023 (compile nil
'(lambda ()
5024 (declare (optimize speed
))
5025 (restart-case () (c ()))))
5026 (compile nil
'(lambda ()
5027 (declare (optimize speed
))
5029 (restart-case (setf x
(car (compute-restarts)))
5033 (with-test (:name
:copy-more-arg
5034 :fails-on
'(not (or :x86
:x86-64
:arm
:arm64
)))
5035 ;; copy-more-arg might not copy in the right direction
5036 ;; when there are more fixed args than stack frame slots,
5037 ;; and thus end up splatting a single argument everywhere.
5038 ;; Failing platforms still start their stack frames at 8 slots, so
5039 ;; this is less likely to happen.
5042 (loop for i below n collect i
))
5043 (test-function (function skip
)
5044 ;; function should just be (subseq x skip)
5045 (loop for i from skip below
(+ skip limit
) do
5046 (let* ((values (iota i
))
5047 (f (apply function values
))
5048 (subseq (subseq values skip
)))
5049 (assert (equal f subseq
)))))
5051 (let ((gensyms (loop for i below n collect
(gensym))))
5052 (compile nil
`(lambda (,@gensyms
&rest rest
)
5053 (declare (ignore ,@gensyms
))
5056 (test-function (make-function i
) i
)))))
5058 (with-test (:name
:apply-aref
)
5061 (handler-bind ((warning (lambda (c) (setf warning c
))))
5062 (compile nil
`(lambda (x y
) (setf (apply #'sbit x y
) 10))))
5063 (assert (not warning
)))))
5064 (test `(lambda (x y
) (setf (apply #'aref x y
) 21)))
5065 (test `(lambda (x y
) (setf (apply #'bit x y
) 1)))
5066 (test `(lambda (x y
) (setf (apply #'sbit x y
) 0)))))
5068 (with-test (:name
:warn-on-the-values-constant
)
5069 (multiple-value-bind (fun warnings-p failure-p
)
5071 ;; The compiler used to elide this test without
5072 ;; noting that the type demands multiple values.
5073 '(lambda () (the (values fixnum fixnum
) 1)))
5074 (declare (ignore warnings-p
))
5075 (assert (functionp fun
))
5076 (assert failure-p
)))
5078 ;; quantifiers shouldn't cons themselves.
5079 (with-test (:name
:quantifiers-no-consing
5080 :skipped-on
'(or :interpreter
5081 (not :stack-allocatable-closures
)))
5082 (let ((constantly-t (lambda (x) x t
))
5083 (constantly-nil (lambda (x) x nil
))
5084 (list (make-list 1000 :initial-element nil
))
5085 (vector (make-array 1000 :initial-element nil
)))
5086 (macrolet ((test (quantifier)
5087 (let ((function (make-symbol (format nil
"TEST-~A" quantifier
))))
5088 `(flet ((,function
(function sequence
)
5089 (,quantifier function sequence
)))
5090 (ctu:assert-no-consing
(,function constantly-t list
))
5091 (ctu:assert-no-consing
(,function constantly-nil vector
))))))
5097 (with-test (:name
:propagate-complex-type-tests
)
5098 (flet ((test (type value
)
5099 (let ((ftype (sb-kernel:%simple-fun-type
5100 (checked-compile `(lambda (x)
5101 (if (typep x
',type
)
5104 (assert (typep ftype
`(cons (eql function
))))
5105 (assert (= 3 (length ftype
)))
5106 (let* ((return (third ftype
))
5107 (rtype (second return
)))
5108 (assert (typep return
`(cons (eql values
)
5110 (cons (eql &optional
)
5112 (assert (and (subtypep rtype type
)
5113 (subtypep type rtype
)))))))
5114 (mapc (lambda (params)
5115 (apply #'test params
))
5116 `(((unsigned-byte 17) 0)
5117 ((member 1 3 5 7) 5)
5118 ((or symbol
(eql 42)) t
)))))
5120 (with-test (:name
:constant-fold-complex-type-tests
)
5121 (assert (equal (sb-kernel:%simple-fun-type
5122 (checked-compile `(lambda (x)
5123 (if (typep x
'(member 1 3))
5124 (typep x
'(member 1 3 15))
5126 `(function (t) (values (member t
) &optional
))))
5127 (assert (equal (sb-kernel:%simple-fun-type
5128 (checked-compile `(lambda (x)
5129 (declare (type (member 1 3) x
))
5130 (typep x
'(member 1 3 15)))))
5131 `(function ((or (integer 1 1) (integer 3 3)))
5132 (values (member t
) &optional
)))))
5134 (with-test (:name
:quietly-row-major-index-no-dimensions
)
5135 (checked-compile `(lambda (x) (array-row-major-index x
))))
5137 (with-test (:name
:array-rank-transform
)
5138 (checked-compile `(lambda (a) (array-rank (the an-imaginary-type a
)))
5139 :allow-style-warnings t
))
5141 (with-test (:name
(:array-rank-fold
:bug-1252108
))
5142 (let ((notes (nth-value
5147 (when (= (array-rank a
) 3)
5148 (array-dimension a
2)))))))))
5149 (assert (= 1 (length notes
)))))
5151 (assert-error (upgraded-array-element-type 'an-undefined-type
))
5153 (with-test (:name
:xchg-misencoding
)
5154 (assert (eql (funcall (checked-compile
5156 (declare (optimize (speed 3) (safety 2))
5157 (type single-float a
))
5163 (with-test (:name
:malformed-declare
)
5165 1 (checked-compile `(lambda (x)
5166 (declare (unsigned-byte (x)))
5168 :allow-failure t
))))
5170 (with-test (:name
:no-dubious-asterisk-warning
)
5173 (macrolet ((frob-some-stuff (&rest exprs
)
5177 (if (symbolp x
) (copy-symbol x
) (gensym)))
5179 `(let ,(mapcar #'list temps exprs
)
5181 (format t
"Got~@{ ~S~^ and~}~%" ,@temps
))))))
5182 (frob-some-stuff *print-base
* (car foo
))))))
5184 (with-test (:name
:interr-type-specifier-hashing
)
5190 (sb-c::type-specifier
5191 (sb-c::specifier-type
5192 `(simple-array ,(sb-vm:saetp-specifier saetp
) (*)))))
5193 sb-vm
:*specialized-array-element-type-properties
*))))
5194 (assert (sb-c::%interr-symbol-for-type-spec
`(or ,@specifiers
)))
5195 (assert (sb-c::%interr-symbol-for-type-spec
5196 `(or ,@specifiers system-area-pointer
)))))
5198 (with-test (:name
:simple-rank-1-array-
*-p-works
)
5199 (assert (funcall (checked-compile
5200 `(lambda () (typep #() '(simple-array * (*)))))))
5201 (loop for saetp across sb-vm
:*specialized-array-element-type-properties
*
5203 (dotimes (n-dimensions 3) ; test ranks 0, 1, and 2.
5204 (let ((dims (make-list n-dimensions
:initial-element
2)))
5205 (dolist (adjustable-p '(nil t
))
5206 (let ((a (make-array dims
:element-type
(sb-vm:saetp-specifier saetp
)
5207 :adjustable adjustable-p
)))
5208 (assert (eq (and (= n-dimensions
1) (not adjustable-p
))
5209 (typep a
'(simple-array * (*)))))))))))
5211 (with-test (:name
:array-subtype-tests
5212 :skipped-on
'(:not
(:or
:x86
:x86-64
)))
5213 (assert (funcall (checked-compile
5215 (typep #() '(or simple-vector simple-string
))))))
5216 (flet ((approx-lines-of-assembly-code (type-expr)
5218 (with-output-to-string (s)
5221 (declare (optimize (sb-c::verify-arg-count
0)))
5222 (typep x
',type-expr
))
5224 ;; These are fragile, but less bad than the possibility of messing up
5225 ;; any vops, especially since the generic code in 'vm-type' checks for
5226 ;; a vop by its name in a place that would otherwise be agnostic of the
5227 ;; backend were it not for my inability to test all platforms.
5228 (assert (< (approx-lines-of-assembly-code
5229 '(simple-array * (*))) 25))
5230 ;; this tested all possible widetags one at a time, e.g. in VECTOR-SAP
5231 (assert (< (approx-lines-of-assembly-code
5232 '(sb-kernel:simple-unboxed-array
(*))) 25))
5233 ;; This is actually a strange type but it's what ANSI-STREAM-READ-N-BYTES
5234 ;; declares as its buffer, which would choke in %BYTE-BLT if you gave it
5235 ;; (simple-array t (*)). But that's a different problem.
5236 (assert (< (approx-lines-of-assembly-code
5237 '(or system-area-pointer
(simple-array * (*)))) 29))
5238 ;; And this was used by %BYTE-BLT which tested widetags one-at-a-time.
5239 (assert (< (approx-lines-of-assembly-code
5240 '(or system-area-pointer
(sb-kernel:simple-unboxed-array
(*))))
5243 (with-test (:name
:local-argument-mismatch-error-string
)
5244 (multiple-value-bind (fun failurep warnings
)
5245 (checked-compile `(lambda (x)
5249 (declare (ignore failurep
))
5250 (assert (= 1 (length warnings
)))
5251 (multiple-value-bind (ok err
) (ignore-errors (funcall fun
42))
5253 (assert (search "FLET FOO" (princ-to-string err
))))))
5255 (with-test (:name
:bug-1310574-0
)
5256 (checked-compile `(lambda (a)
5258 ((or (array * (* * 3)) (array * (* * 4)))
5259 (case (array-rank a
)
5260 (2 (aref a
1 2))))))))
5262 (with-test (:name
:bug-1310574-1
)
5263 (checked-compile `(lambda (a)
5265 ((or (array * ()) (array * (1)) (array * (1 2)))
5266 (case (array-rank a
)
5267 (3 (aref a
1 2 3))))))))
5269 (with-test (:name
:bug-573747
)
5271 1 (checked-compile `(lambda (x) (progn (declare (integer x
)) (* x
6)))
5272 :allow-failure t
))))
5274 ;; Something in this function used to confuse lifetime analysis into
5275 ;; recording multiple conflicts for a single TNs in the dolist block.
5276 (with-test (:name
:bug-1327008
)
5277 (handler-bind (((or style-warning compiler-note
)
5279 (muffle-warning c
))))
5281 `(lambda (scheduler-spec
5282 schedule-generation-method
5283 utc-earliest-time utc-latest-time
5284 utc-other-earliest-time utc-other-latest-time
5289 maximum-connection-time
5292 permitted-route-locations prohibited-route-locations
5293 preferred-connection-locations disfavored-connection-locations
5294 origins destinations
5295 permitted-carriers prohibited-carriers
5296 permitted-operating-carriers prohibited-operating-carriers
5297 start-airports end-airports
5299 specified-circuity-limit-extra-miles
5300 (preferred-carriers :unspecified
)
5302 (declare (optimize speed
))
5303 (let ((table1 (list nil
))
5305 (skip-flifo-checks (getf scheduler-spec
:skip-flifo-checks
))
5306 (construct-gaps-p (getf scheduler-spec
:construct-gaps-p
))
5307 (gap-locations (getf scheduler-spec
:gap-locations
))
5308 (result-array (make-array 100))
5313 (prev-start-airports origins
)
5314 (prev-end-airports destinations
)
5315 (prev-permitted-carriers permitted-carriers
))
5316 (flet ((run-with-hint (hint random-magic other-randomness
5319 preferred-destinations
5321 (let* ((hint-permitted-carriers (first hint
))
5322 (preferred-end-airports
5323 (ecase schedule-generation-method
5324 (:DEPARTURE preferred-destinations
)
5325 (:ARRIVAL preferred-origins
)))
5326 (revised-permitted-carriers
5327 (cond ((and hint-permitted-carriers
5328 (not (eq permitted-carriers
:ANY
)))
5329 (intersection permitted-carriers
5330 hint-permitted-carriers
))
5331 (hint-permitted-carriers)
5332 (permitted-carriers)))
5333 (revised-maximum-mileage
5334 (min (let ((maximum-mileage 0))
5335 (dolist (o start-airports
)
5336 (dolist (d end-airports
)
5337 (setf maximum-mileage
5338 (max maximum-mileage
(mileage o d
)))))
5339 (round (+ (* circuity-limit maximum-mileage
)
5340 (or specified-circuity-limit-extra-miles
5341 (hairy-calculation slice-number
)))))
5343 (when (or (not (equal start-airports prev-start-airports
))
5344 (not (equal end-airports prev-end-airports
))
5345 (and (not (equal revised-permitted-carriers
5346 prev-permitted-carriers
))))
5350 permitted-operating-carriers
5351 prohibited-operating-carriers
5352 permitted-route-locations
5353 prohibited-route-locations
5357 (setf prev-permitted-carriers revised-permitted-carriers
))
5358 (multiple-value-bind (this-number-dequeued
5361 (apply #'schedule-loop
5362 utc-earliest-time utc-other-earliest-time
5363 utc-latest-time utc-other-latest-time
5364 scheduler-spec schedule-generation-method
5366 :maximum-mileage revised-maximum-mileage
5367 :maximum-extra-legs maximum-extra-legs
5368 :maximum-connection-time maximum-connection-time
5369 :same-pass-p same-pass-p
5370 :preferred-end-airports preferred-end-airports
5371 :maximum-blah random-magic
5372 :skip-flifo-checks skip-flifo-checks
5375 :preferred-connection-locations preferred-connection-locations
5376 :disfavored-connection-locations disfavored-connection-locations
5378 (when other-randomness
5379 (loop for i fixnum from n-new to
(+ n-new
(1- this-n-new
))
5380 do
(hairy-calculation i result-array
)))
5381 (incf number-dequeued this-number-dequeued
)
5382 (incf n-new this-n-new
)
5383 (setq exit-reason
(logior exit-reason this-exit-reason
))))))
5384 (let ((n-hints-processed 0))
5385 (dolist (hint scheduler-hints
)
5386 (run-with-hint hint n-hints-processed t
0
5388 (incf n-hints-processed
)))
5389 (run-with-hint nil
42 nil maximum-extra-legs
5393 (with-test (:name
:dead-code-in-optional-dispatch
)
5394 ;; the translation of each optional entry is
5395 ;; (let ((#:g (error "nope"))) (funcall #<clambda> ...))
5396 ;; but the funcall is unreachable. Since this is an artifact of how the
5397 ;; lambda is converted, it should not generate a note as if in user code.
5399 `(lambda (a &optional
(b (error "nope")) (c (error "nope")))
5402 (with-test (:name
:nth-value-of-non-constant-N
:skipped-on
:interpreter
)
5403 (labels ((foo (n f
) (nth-value n
(funcall f
)))
5404 (bar () (values 0 1 2 3 4 5 6 7 8 9)))
5405 (assert (= (foo 5 #'bar
) 5)) ; basic correctness
5406 (assert (eq (foo 12 #'bar
) nil
))
5407 (ctu:assert-no-consing
(eql (foo 953 #'bar
) 953))))
5409 (with-test (:name
:position-derive-type-optimizer
)
5410 (assert-code-deletion-note
5411 '(lambda (x) ; the call to POSITION can't return 4
5412 (let ((i (position x
#(a b c d
) :test
'eq
)))
5413 (case i
(4 'nope
) (t 'okeydokey
))))))
5415 ;; Assert that DO-PACKED-TNS has unsurprising behavior if the body RETURNs.
5416 ;; This isn't a test in the problem domain of CL - it's of an internal macro,
5417 ;; and x86-64-specific not because of broken-ness, but because it uses
5418 ;; known random TNs to play with. Printing "skipped on" for other backends
5419 ;; would be somewhat misleading in as much as it means nothing about
5420 ;; the correctness of the test on other architectures.
5422 (with-test (:name
:do-packed-tn-iterator
)
5423 (dotimes (i (ash 1 6))
5424 (labels ((make-tns (n)
5425 (mapcar 'copy-structure
5426 (subseq `sb-vm
::(,rax-tn
,rbx-tn
,rcx-tn
) 0 n
)))
5429 (setf (sb-c::tn-next
(car list
)) (link (cdr list
)))
5431 (let* ((normal (make-tns (ldb (byte 2 0) i
)))
5432 (restricted (make-tns (ldb (byte 2 2) i
)))
5433 (wired (make-tns (ldb (byte 2 4) i
)))
5434 (expect (append normal restricted wired
))
5435 (comp (sb-c::make-empty-component
))
5436 (ir2-comp (sb-c::make-ir2-component
)))
5437 (setf (sb-c::component-info comp
) ir2-comp
5438 (sb-c::ir2-component-normal-tns ir2-comp
) (link normal
)
5439 (sb-c::ir2-component-restricted-tns ir2-comp
) (link restricted
)
5440 (sb-c::ir2-component-wired-tns ir2-comp
) (link wired
))
5442 (result (sb-c::do-packed-tns
(tn comp
42) (push tn list
))))
5443 (assert (eq result
42))
5444 (assert (equal expect
(nreverse list
))))
5446 (result (sb-c::do-packed-tns
(tn comp
'bar
)
5448 (if (= (incf n
) 4) (return 'foo
)))))
5449 (assert (eq result
(if (>= (length expect
) 4) 'foo
'bar
)))
5450 (assert (equal (subseq expect
0 (min 4 (length expect
)))
5451 (nreverse list
))))))))
5454 (with-test (:name
(optimize :quality-multiply-specified
:bug-310267
))
5455 (let ((sb-c::*policy
* sb-c
::*policy
*)) ; to keep this test pure
5456 (assert-signal (proclaim '(optimize space debug
(space 0)))
5459 (assert (= 1 (length (nth-value
5461 form
:allow-style-warnings t
)))))))
5462 (test `(lambda () (declare (optimize speed
(speed 0))) 5))
5463 (test `(lambda () (declare (optimize speed
) (optimize (speed 0))) 5))
5465 (declare (optimize speed
)) (declare (optimize (speed 0)))
5469 (assert-no-signal (proclaim '(optimize (space 3) space
)))
5470 (checked-compile `(lambda () (declare (optimize speed
(speed 3))) 5))
5471 (checked-compile `(lambda () (declare (optimize speed
) (optimize (speed 3))) 5))
5472 (checked-compile `(lambda ()
5473 (declare (optimize speed
)) (declare (optimize (speed 3)))
5476 (with-test (:name
(truncate :type-derivation
))
5477 (assert (= 4 (funcall (checked-compile
5479 (truncate a
(the (rational (1) (3)) b
))))
5482 (with-test (:name
:constantp-on-a-literal-function-works
)
5483 (assert (constantp `(the (function (list) t
) ,#'car
))))
5485 (with-test (:name
:arg-count-error
)
5486 (assert (eq :win
(handler-case (funcall (intern "CONS") 1 2 3)
5487 (sb-int:simple-program-error
() :win
)
5488 (condition () :lose
)))))
5490 (with-test (:name
:mv-conversion
)
5491 (checked-compile `(lambda (a)
5493 (list (unwind-protect a
))
5494 (multiple-value-call #'list
5495 (values (catch 'ct5
(go 0))))
5498 (with-test (:name
(:null-cleanups-1
:bug-1416704
:bug-404441
))
5503 (declare (optimize speed
))
5505 (funcall (flet ((bar () 10)) #'bar
))
5506 (funcall (flet ((fez ()
5507 (funcall (flet ((foo () 20)) #'foo
))))
5509 (assert (= (funcall x t
) 10))
5510 (assert (= (funcall x nil
) 20))))
5512 (with-test (:name
(:null-cleanups-2
:bug-1416704
:bug-404441
))
5517 (declare (optimize speed
))
5518 (let* ((a2 (lambda () 20))
5520 (a0 (flet ((f () (funcall a2
)))
5526 (let ((a5 (lambda () (funcall a4
))))
5530 (assert (= (catch 'x
(funcall fun t
)) 10))
5531 (assert (= (catch 'x
(funcall fun nil
)) 20))))
5534 (with-test (:name
:locall-already-let-converted
)
5535 (assert (eq (funcall
5540 (flet ((f () (return-from f ff
)))
5541 (declare (inline f
))
5544 (declare (inline call
))
5546 (call (lambda () 'result
)))))))
5549 (with-test (:name
:debug-dump-elsewhere
)
5550 (assert (eql (catch 'x
5554 (declare (optimize debug
))
5558 (with-test (:name
(typep :quasiquoted-constant
))
5559 (assert (null (ctu:find-named-callees
5562 (typep x
`(signed-byte ,sb-vm
:n-word-bits
))))))))
5564 (with-test (:name
(logior :transform
))
5565 (multiple-value-bind (fun failurep warnings
)
5566 (checked-compile `(lambda (c)
5569 (logior c
(f nil
))))
5572 (assert (= 1 (length warnings
)))
5573 (assert-error (funcall fun
10) type-error
)))
5575 (with-test (:name
:eql
/integer-folding
)
5578 (fceiling (the (member 2.3 21672589639883401935) a
)))))
5580 (with-test (:name
(position :derive-type
))
5581 (let ((f (checked-compile
5583 (declare (type (simple-string 90) x
))
5584 (declare (muffle-conditions code-deletion-note
))
5585 (let ((b (position #\i x
)))
5586 (if (and (integerp b
) (> b
100))
5587 'yikes
'okey-dokey
))))))
5588 ;; The function can not return YIKES
5589 (assert (not (ctu:find-code-constants f
:type
'(eql yikes
))))))
5591 (with-test (:name
:compile-file-error-position-reporting
)
5592 (dolist (input '("data/wonky1.lisp" "data/wonky2.lisp" "data/wonky3.lisp"))
5593 (let ((expect (with-open-file (f input
) (read f
))))
5594 (assert (stringp expect
))
5595 (let ((err-string (with-output-to-string (*error-output
*)
5596 (compile-file input
:print nil
))))
5597 (assert (search expect err-string
))))))
5599 (with-test (:name
(coerce :derive-type
))
5600 (macrolet ((check (type ll form
&rest values
)
5601 `(assert (equal (funcall (checked-compile
5603 (ctu:compiler-derived-type
,',form
)))
5610 (check (unsigned-byte 32)
5612 (coerce a
'(unsigned-byte 32))
5616 (coerce a
(array-element-type (the (array character
) x
)))
5619 (check (unsigned-byte 32)
5621 (coerce a
(array-element-type (the (array (unsigned-byte 32)) x
)))
5623 (make-array 10 :element-type
'(unsigned-byte 32)))))
5625 (with-test (:name
:associate-args
)
5626 (flet ((test (form argument
)
5627 (multiple-value-bind (fun failurep warnings
)
5628 (checked-compile form
:allow-warnings t
)
5630 (assert (= 1 (length warnings
)))
5631 (assert-error (funcall fun argument
)))))
5632 (test `(lambda (x) (+ 1 x nil
)) 2)
5633 (test `(lambda (x) (/ 1 x nil
)) 4)))
5635 (with-test (:name
:eager-substitute-single-use-lvar
)
5639 (declare (optimize (debug 0) (safety 0)))
5640 (let ((a (the fixnum a
))
5644 (flet ((jump () (go loop
)))
5647 (setf z
(the fixnum
(if (= x
1) #xFFF a
)))
5654 (with-test (:name
:vop-on-eql-type
)
5656 (funcall (compile nil
5658 (declare ((eql -
7) b
)
5667 (multiple-value-bind (fun failurep
)
5668 (checked-compile `(lambda () ,form
)
5671 (assert-error (funcall fun
) sb-int
:compiled-program-error
))))
5673 (with-test (:name
(compile macrolet
:malformed
))
5674 (test '(macrolet (foo () 'bar
)))
5675 (test '(macrolet x
))
5676 (test '(symbol-macrolet x
))
5677 (test '(symbol-macrolet (x))))
5679 (with-test (:name
(compile flet
:malformed
))
5680 (test '(flet (foo () 'bar
)))
5682 (test '(labels (foo () 'bar
)))
5683 (test '(labels x
))))
5685 (with-test (:name
:compile-load-time-value-interpreted-mode
)
5686 ;; This test exercises the same pattern as HANDLER-BIND (to a
5687 ;; degree). In particular a HANDLER-BIND that was compiled when the
5688 ;; *EVALUATOR-MODE* was :INTERPRET would not compile its class
5689 ;; predicates, because LOAD-TIME-VALUE just called EVAL, and you
5690 ;; would get back a list with an interpreted function in it.
5692 ;; In the code below, this function when called would generate a new
5693 ;; symbol each time. But if the compiler processes the guts as it
5694 ;; should, you get back a compiled lambda which returns a constant
5696 (let ((f (let ((sb-ext:*evaluator-mode
* :interpret
))
5702 (sb-int:keywordicate
(gensym))))
5704 (eq (funcall (car (funcall f
)))
5705 (funcall (car (funcall f
))))))
5707 (with-test (:name
:constant-fold-%eql
/integer
)
5709 (funcall (checked-compile
5711 (declare (type (complex single-float
) x
)
5712 (optimize (debug 2)))
5713 (member (the (eql #c
(0.0
0.0)) x
)
5714 '(1 2 3 9912477572127105188))))
5717 (with-test (:name
(compile svref
:constant
))
5719 (= (funcall (checked-compile
5720 `(lambda () (svref #(1 2 3) 1))))
5723 (with-test (:name
(compile char-equal
:type-intersection
))
5725 (eq (funcall (checked-compile
5727 (char-equal (the (member #\a #\B
) x
)
5728 (the (eql #\A
) y
))))
5732 (with-test (:name
(oddp fixnum
:no-consing
))
5733 (let ((f (compile nil
'(lambda (x) (oddp x
)))))
5734 (ctu:assert-no-consing
(funcall f most-positive-fixnum
))))
5735 (with-test (:name
(oddp bignum
:no-consing
))
5736 (let ((f (compile nil
'(lambda (x) (oddp x
))))
5737 (x (* most-positive-fixnum most-positive-fixnum
3)))
5738 (ctu:assert-no-consing
(funcall f x
))))
5739 (with-test (:name
(logtest fixnum
:no-consing
:bug-1277690
))
5740 (let ((f (compile nil
'(lambda (x) (logtest x most-positive-fixnum
)))))
5741 (ctu:assert-no-consing
(funcall f
1))))
5742 (with-test (:name
(logtest bignum
:no-consing
))
5743 (let ((f (compile nil
'(lambda (x) (logtest x
1))))
5744 (x (* most-positive-fixnum most-positive-fixnum
3)))
5745 (ctu:assert-no-consing
(funcall f x
))))
5747 (with-test (:name
(:randomized
:mask-signed-field
))
5750 (let* ((ool (compile nil
'(lambda (s i
) (sb-c::mask-signed-field s i
))))
5751 (size (random (* sb-vm
:n-word-bits
2)))
5752 (constant (compile nil
`(lambda (i) (sb-c::mask-signed-field
,size i
))))
5753 (arg (- (random (* most-positive-fixnum
8)) (* most-positive-fixnum
4)))
5754 (declared (compile nil
`(lambda (i) (declare (type (integer ,(- (abs arg
)) ,(abs arg
)) i
)) (sb-c::mask-signed-field
,size i
))))
5755 (ool-answer (funcall ool size arg
))
5756 (constant-answer (funcall constant arg
))
5757 (declared-answer (funcall declared arg
)))
5758 (unless (= ool-answer constant-answer declared-answer
)
5759 (push (list size arg ool-answer constant-answer declared-answer
) result
))))
5760 (assert (null result
))))
5762 (with-test (:name
:array-dimensions-
*)
5763 (= (funcall (compile nil
`(lambda (array)
5764 (declare ((or (vector t
) (array character
)) array
))
5765 (array-dimension array
0)))
5769 (with-test (:name
:generate-type-checks-on-dead-blocks
)
5770 (assert (equalp (funcall (compile nil
`(lambda (a b
)
5771 (declare (optimize (safety 3))
5772 (type (member vector
42) a
))
5773 (map a
'list
(the vector b
) #*)))
5777 (with-test (:name
(make-list :large
1))
5778 (checked-compile `(lambda ()
5779 (make-list (expt 2 28) :initial-element
0))))
5781 (with-test (:name
(make-list :large
2)
5782 :skipped-on
'(not :64-bit
))
5783 (checked-compile `(lambda ()
5784 (make-list (expt 2 30) :initial-element
0))))
5786 (with-test (:name
:bad-cond
)
5789 '(lambda () (cond (t 10) 20)))))
5791 (with-test (:name
:removed-dx-cast
)
5793 (checked-compile `(lambda ()
5795 (let ((x (the integer
(return 0))))
5796 (declare (dynamic-extent x
))
5797 (unwind-protect x
1))))))
5800 (with-test (:name
:isqrt-derivation
)
5801 (assert (eql (funcall (checked-compile
5803 (isqrt (count (the bit i
) #*11101))))
5807 (with-test (:name
:vector-zero-initialization
)
5808 (assert (equalp (funcall (funcall (checked-compile
5810 (declare ((eql 0) x
)
5811 (optimize (debug 2)))
5813 (vector x
(isqrt b
)))))
5817 (with-test (:name
:cons-zero-initialization
)
5818 (assert (equalp (funcall (funcall (checked-compile
5820 (declare ((eql 0) x
)
5821 (optimize (debug 2)))
5823 (cons x
(isqrt b
)))))
5827 (with-test (:name
:check-important-result-warning
)
5828 (multiple-value-bind (fun failure warnings style-warnings
)
5829 (checked-compile '(lambda (x z
)
5830 (declare (notinline nintersection
))
5831 (nintersection x z
) x
)
5832 :allow-style-warnings t
)
5833 (declare (ignore fun failure warnings
))
5834 (loop for c in style-warnings
5836 (assert (search "NINTERSECTION"
5837 (princ-to-string c
))))))
5839 (with-test (:name
:destroyed-constant-warning
)
5840 (multiple-value-bind (fun failure warnings
)
5841 (checked-compile '(lambda ()
5842 (declare (notinline nunion
))
5843 (nunion '(1 2 3) '(1 2 4)))
5845 (declare (ignore fun failure
))
5846 (loop for c in warnings
5848 (assert (search "NUNION"
5849 (princ-to-string c
))))))
5851 (with-test (:name
:%array-data-vector-complex-type-derivation
)
5852 (let ((type (funcall (checked-compile
5854 (ctu:compiler-derived-type
(sb-kernel:%array-data-vector
(the array x
)))))
5856 (assert (eq type
'array
))))
5858 (with-test (:name
:equalp-transofrm
)
5860 (funcall (checked-compile
5862 (equalp (the (simple-array single-float
(*)) x
)
5863 (the (simple-array double-float
(*)) y
))))
5864 (coerce '(1f0) '(simple-array single-float
(*)))
5865 (coerce '(1d0) '(simple-array double-float
(*))))))
5867 (with-test (:name
:array-hairy-type-derivation
)
5869 (equal (funcall (checked-compile
5871 (subseq (the (and (satisfies sb-impl
::vector-with-fill-pointer-p
)
5874 (make-array 3 :element-type
'character
5876 :initial-contents
"abc"))
5879 (with-test (:name
:nreverse-derive-type
)
5881 (not (funcall (checked-compile
5883 (eql (car (nreverse (the (cons (eql 10)) x
))) 10)))
5886 (with-test (:name
:subseq-derive-type
)
5888 (equalp (funcall (checked-compile
5890 (subseq (the (simple-vector 3) x
) 1)))
5894 (with-test (:name
:sequence-derive-type
)
5896 (equalp (funcall (checked-compile
5898 (copy-seq (the (and string
(not (simple-array nil
))) x
))))
5899 (make-array 3 :element-type
'character
5901 :initial-contents
"123"))
5904 (with-test (:name
:sequence-derive-type
.2)
5906 (funcall (checked-compile
5908 (equal (the (and string
(not (simple-array nil
))) x
) y
)))
5909 (make-array 3 :element-type
'character
5911 :initial-contents
"123")
5914 (with-test (:name
:sequence-derive-type
.3)
5916 (equalp (funcall (checked-compile
5918 (subseq (the (or (simple-array * (*)) string
) x
) 0 2)))
5922 (with-test (:name
:not-enough-values-cast
)
5924 (not (funcall (checked-compile
5926 (car (describe 1 (make-broadcast-stream)))))))))
5928 ;; Vestigial exit deletion was a bit too aggressive, causing stack
5929 ;; analysis to decide that the value of (BAR 10) in both cases below
5930 ;; needed to be nipped out from under the dynamic-extent allocation of
5931 ;; Y (or #'Y), which %NIP-VALUES refused to do (DX values must not be
5932 ;; moved once allocated).
5933 (with-test (:name
(:exit-deletion
:bug-1563127
:variable
))
5934 (compile nil
'(lambda (x)
5936 (multiple-value-prog1 (bar 10)
5938 (declare (dynamic-extent y
))
5941 (return-from test
))))))))
5943 (with-test (:name
(:exit-deletion
:bug-1563127
:function
))
5944 (compile nil
'(lambda (x)
5946 (multiple-value-prog1 (bar 10)
5947 (flet ((y () (list x
)))
5948 (declare (dynamic-extent #'y
))
5951 (return-from test
))))))))