1 ;;;; This file is for compiler tests which have side effects (e.g.
2 ;;;; executing DEFUN) but which don't need any special side-effecting
3 ;;;; environmental stuff (e.g. DECLAIM of particular optimization
4 ;;;; settings). Similar tests which *do* expect special settings may
5 ;;;; be in files compiler-1.impure.lisp, compiler-2.impure.lisp, etc.
7 ;;;; This software is part of the SBCL system. See the README file for
10 ;;;; While most of SBCL is derived from the CMU CL system, the test
11 ;;;; files (like this one) were written from scratch after the fork
14 ;;;; This software is in the public domain and is provided with
15 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
16 ;;;; more information.
20 ;; The tests in this file do not work under the legacy interpreter.
21 ;; They mostly do work in the fast interpreter, and are either harmless
22 ;; or actually reasonable things to test.
23 (when (and (eq sb-ext
:*evaluator-mode
* :interpret
)
24 (not (member :sb-fasteval
*features
*)))
25 (sb-ext:exit
:code
104))
27 (load "compiler-test-util.lisp")
28 (use-package "TEST-UTIL")
29 (use-package "ASSERTOID")
31 ;;; Old CMU CL code assumed that the names of "keyword" arguments are
32 ;;; necessarily self-evaluating symbols, but ANSI Common Lisp allows
33 ;;; them to be any symbols, not necessarily keywords, and thus not
34 ;;; necessarily self-evaluating. Make sure that this works.
35 (defun newfangled-cons (&key
((left-thing x
)) ((right-thing y
)))
37 (with-test (:name
(:lambda-list
&key
:self-evaluating
))
38 (assert (equal (cons 1 2) (newfangled-cons 'right-thing
2 'left-thing
1))))
40 ;;; ANSI specifically says that duplicate keys are OK in lambda lists,
41 ;;; with no special exception for macro lambda lists. (As reported by
42 ;;; Pierre Mai on cmucl-imp 2001-03-30, Python didn't think so. The
43 ;;; rest of the thread had some entertainment value, at least for me
44 ;;; (WHN). The unbelievers were besmote and now even CMU CL will
45 ;;; conform to the spec in this regard. Who needs diplomacy when you
46 ;;; have brimstone?:-)
47 (defmacro ayup-duplicate-keys-are-ok-i-see-the-lite
(&key k
)
49 (with-test (:name
(:macro
:lambda-list
:duplicate
&key
:arguments
))
50 (checked-compile-and-assert ()
52 (ayup-duplicate-keys-are-ok-i-see-the-lite :k
112))
54 (checked-compile-and-assert ()
56 (ayup-duplicate-keys-are-ok-i-see-the-lite :k
'x
:k
'y
))
59 ;;; Lexically binding a name that is 1) bound to a global symbol macro
60 ;;; 2) at home in a locked package
62 (defpackage #:package-for-global-symbol-macro
(:lock t
))
63 (cl:in-package
#:package-for-global-symbol-macro
)
64 (cl:define-symbol-macro global-symbol-macro
1)
65 (cl:in-package
#:cl-user
)
67 (with-test (:name
(let define-symbol-macro
:locked package
))
68 (multiple-value-bind (fun failure-p warnings
)
70 '(lambda () (let ((package-for-global-symbol-macro::global-symbol-macro
1))
71 package-for-global-symbol-macro
::global-symbol-macro
))
72 :allow-failure t
:allow-warnings t
)
73 (declare (ignore fun
))
77 ;;; As reported by Alexey Dejneka (sbcl-devel 2002-01-30), in
78 ;;; sbcl-0.7.1 plus his patch (i.e. essentially sbcl-0.7.1.2), the
79 ;;; compiler barfed on this, blowing up in FIND-IN-PHYSENV looking for
80 ;;; the LAMBDA-VAR named NUM. That was fixed in sbcl-0.7.1.3.
81 (defun parse-num (index)
88 (when (and (digs) (digs)) x
))))
90 ;;; Bug 132: The compiler used to fail to compile INTEGER-valued CATCH
91 ;;; tags. This was fixed by Alexey Dejneka in sbcl-0.7.1.14. (INTEGER
92 ;;; catch tags are still a bad idea because EQ is used to compare
93 ;;; tags, and EQ comparison on INTEGERs is unportable; but now it's a
94 ;;; compiler warning instead of a failure to compile.)
95 (with-test (:name
(compile catch
:integer-valued-tag
:bug-132
))
96 (multiple-value-bind (fun failure-p warnings style-warnings
)
97 (checked-compile '(lambda () (catch 0 (print 1331 (make-broadcast-stream))))
98 :allow-style-warnings t
)
99 (declare (ignore failure-p warnings
))
101 (assert style-warnings
)))
103 ;;; Bug 150: In sbcl-0.7.1.15, compiling this code caused a failure in
104 ;;; SB-C::ADD-TEST-CONSTRAINTS:
105 ;;; The value NIL is not of type SB-C::CONTINUATION.
106 ;;; This bug was fixed by APD in sbcl-0.7.1.30.
107 (defun bug150-test1 ()
109 (flet ((wufn () (glorp table1
4.9)))
110 (gleep *uustk
* #'wufn
"#1" (list)))
111 (if (eql (lo foomax
3.2))
113 (error "not ~S" '(eql (lo foomax
3.2))))
115 ;;; A simpler test case for bug 150: The compiler died with the
116 ;;; same type error when trying to compile this.
117 (defun bug150-test2 ()
121 ;;; bug 147, fixed by APD 2002-04-28
123 ;;; This test case used to crash the compiler, e.g. with
124 ;;; failed AVER: "(= (LENGTH (BLOCK-SUCC CALL-BLOCK)) 1)"
125 (defun bug147 (string ind
)
129 (typep (char string ind
) '(member #\
1)))
132 ;;; bug reported and fixed by Matthias Hoelzl sbcl-devel 2002-05-13
133 (defmacro foo-2002-05-13
() ''x
)
134 (eval '(foo-2002-05-13))
135 (compile 'foo-2002-05-13
)
136 (foo-2002-05-13) ; (The bug caused UNDEFINED-FUNCTION to be signalled here.)
138 ;;; floating point pain on the PPC.
140 ;;; This test case used to fail to compile on most powerpcs prior to
141 ;;; sbcl-0.7.4.2x, as floating point traps were being incorrectly
143 (defun floating-point-pain (x)
144 (declare (single-float x
))
147 ;;; bug found and fixed ca. sbcl-0.7.5.12: The INTERSECTION-TYPE
148 ;;; here satisfies "is a subtype of ARRAY-TYPE", but can't be
149 ;;; accessed with ARRAY-TYPE accessors like
150 ;;; ARRAY-TYPE-SPECIALIZED-ELEMENT-TYPE, so ARRAY-related
151 ;;; DEFTRANSFORMs died with TYPE-ERROR at compile time when
152 ;;; compiling the DEFUN here.
153 (defun stupid-input-to-smart-array-deftransforms-0-7-5-12 (v)
154 (declare (type (and simple-vector fwd-type-ref
) v
))
157 ;;; Ca. sbcl-0.7.5.15 the compiler would fail an internal consistency
158 ;;; check on this code because it expected all calls to %INSTANCE-REF
159 ;;; to be transformed away, but its expectations were dashed by perverse
160 ;;; code containing app programmer errors like this.
161 (defstruct something-known-to-be-a-struct x y
)
162 (with-test (:name
(compile defstruct
:instance-ref
))
165 ;; Python sees the structure accessor on the
166 ;; known-not-to-be-a-struct A5 value and is very, very
167 ;; disappointed in you. (But it doesn't signal BUG any
171 (cond (t (a4 a2 a3
))))
173 (declare (type (or simple-vector null
) a5 a6
))
174 (something-known-to-be-a-struct-x a5
))
178 (cond ((and (funcall a12 a2
)
183 (let ((a15 (a1 a2 a3
)))
186 (values #'a17
#'a11
)))
187 :allow-failure t
:allow-warnings t
:allow-style-warnings t
))))
189 ;;; On the SPARC, there was an erroneous definition of some VOPs used
190 ;;; to compile LOGANDs, which would lead to compilation of the
191 ;;; following function giving rise to a compile-time error (bug
192 ;;; spotted and fixed by Raymond Toy for CMUCL)
193 (defun logand-sparc-bogons (a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
)
194 (declare (type (unsigned-byte 32) a0
)
195 (type (signed-byte 32) a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
)
196 ;; to ensure that the call is a candidate for
198 (optimize (speed 3) (safety 0) (compilation-speed 0) (debug 0)))
200 ;; the call that fails compilation
202 ;; a call to prevent the other arguments from being optimized away
203 (logand a1 a2 a3 a4 a5 a6 a7 a8 a9
)))
205 ;;; bug 192, reported by Einar Floystad Dorum sbcl-devel 2002-08-14,
206 ;;; fixed in sbcl-0.7.6.26: Compiling this function in 0.7.6 caused
207 ;;; the compiler to try to constant-fold DATA-VECTOR-REF, which is OK,
208 ;;; except that there was no non-VOP definition of DATA-VECTOR-REF, so
220 (DECLARE (IGNORABLE S E
))
230 (DECLARE (IGNORABLE S E
))
231 (WHEN (EQL #\b E
) (G910 (1+ I
)))))))
238 (DECLARE (IGNORABLE S
))
241 (G908 I
))) "abcdefg" 0 (length "abcdefg")))
243 ;;; bugs #65, #70, and #109, closed by APD's patch sbcl-devel 2002-08-17
245 ;;; This was "YA code deletion bug" whose symptom was the failure of
247 ;;; (EQ (C::LAMBDA-TAIL-SET C::CALLER)
248 ;;; (C::LAMBDA-TAIL-SET (C::LAMBDA-HOME C::CALLEE)))
250 (defun bug65-1 (termx termy
) ; from Carl Witty on submit bugs list, debian.org
252 ((alpha-equal-bound-term-lists (listx listy
)
253 (or (and (null listx
) (null listy
))
255 (let ((bindings-x (bindings-of-bound-term (car listx
)))
256 (bindings-y (bindings-of-bound-term (car listy
))))
257 (if (and (null bindings-x
) (null bindings-y
))
258 (alpha-equal-terms (term-of-bound-term (car listx
))
259 (term-of-bound-term (car listy
)))
260 (and (= (length bindings-x
) (length bindings-y
))
262 (enter-binding-pairs (bindings-of-bound-term (car listx
))
263 (bindings-of-bound-term (car listy
)))
264 (alpha-equal-terms (term-of-bound-term (car listx
))
265 (term-of-bound-term (car listy
)))
266 (exit-binding-pairs (bindings-of-bound-term (car listx
))
267 (bindings-of-bound-term (car listy
)))))))
268 (alpha-equal-bound-term-lists (cdr listx
) (cdr listy
)))))
270 (alpha-equal-terms (termx termy
)
271 (if (and (variable-p termx
)
273 (equal-bindings (id-of-variable-term termx
)
274 (id-of-variable-term termy
))
275 (and (equal-operators-p (operator-of-term termx
) (operator-of-term termy
))
276 (alpha-equal-bound-term-lists (bound-terms-of-term termx
)
277 (bound-terms-of-term termy
))))))
281 (with-variable-invocation (alpha-equal-terms termx termy
))))))
282 (defun bug65-2 () ; from Bob Rogers cmucl-imp 1999-07-28
283 ;; Given an FSSP alignment file named by the argument . . .
284 (labels ((get-fssp-char ()
288 ;; Stub body, enough to tickle the bug.
289 (list (read-fssp-char)
291 (defun bug70 ; from David Young cmucl-help 30 Nov 2000
292 (item sequence
&key
(test #'eql
))
293 (labels ((find-item (obj seq test
&optional
(val nil
))
294 (let ((item (first seq
)))
297 ((funcall test obj item
)
303 (nconc val
`(,item
))))))))
304 (find-item item sequence test
)))
305 (defun bug109 () ; originally from CMU CL bugs collection, reported as
306 ; SBCL bug by MNA 2001-06-25
311 ;; Uncomment and it works
315 ;;; bug 192a, fixed by APD "more strict type checking" patch
316 ;;; (sbcl-devel 2002-08-07)
318 (declare (optimize (speed 0) (safety 3)))
319 ;; Even with bug 192a, this declaration was checked as an assertion.
323 ;; Because of bug 192a, this declaration was trusted without checking.
324 (declare (single-float x
))
326 (with-test (:name
(declare type
:bug-192a
))
327 (assert-error (bug192a nil
) type-error
)
328 (multiple-value-bind (result error
) (ignore-errors (bug192a 100))
329 (assert (null result
))
330 (assert (equal (type-error-expected-type error
) 'single-float
))))
332 ;;; bug 194, fixed in part by APD "more strict type checking" patch
333 ;;; (sbcl-devel 2002-08-07)
334 (with-test (:name
(the :bug-194
))
335 (assert-error (multiple-value-prog1 (progn (the real
'(1 2 3)))) type-error
)
336 (assert-error (the real
'(1 2 3)) type-error
))
341 (arg2 (identity (the real
#(1 2 3)))))
342 (if (< arg1 arg2
) arg1 arg2
)))))
343 (with-test (:name
(the :bug-194d
))
344 (assert (eq (bug194d) t
)))
347 ;;; BUG 48a. and b. (symbol-macrolet handling), fixed by Eric Marsden
348 ;;; and Raymond Toy for CMUCL, fix ported for sbcl-0.7.6.18.
350 (multiple-value-bind (function failure-p
)
351 (checked-compile form
:allow-failure t
)
353 (assert-error (funcall function
) program-error
))))
355 (with-test (:name
(compile symbol-macrolet
:bug-48a
))
357 ;; not interested in the package lock violation here
358 (declare (sb-ext:disable-package-locks t
))
359 (symbol-macrolet ((t nil
)) t
))))
361 (with-test (:name
(compile symbol-macrolet
:bug-48b
))
363 ;; not interested in the package lock violation here
364 (declare (sb-ext:disable-package-locks
*standard-input
*))
365 (symbol-macrolet ((*standard-input
* nil
))
368 (with-test (:name
(compile symbol-macrolet
:bug-48c
))
370 (symbol-macrolet ((s nil
)) (declare (special s
)) s
)))))
373 ;;; bug 120a: Turned out to be constraining code looking like (if foo
374 ;;; <X> <X>) where <X> was optimized by the compiler to be the exact
375 ;;; same block in both cases, but not turned into (PROGN FOO <X>).
376 ;;; Fixed by APD in sbcl-0.7.7.2, who provided this test:
377 (declaim (inline dont-constrain-if-too-much
))
378 (defun dont-constrain-if-too-much (frame up-frame
)
379 (declare (optimize (speed 3) (safety 1) (debug 1)))
380 (if (or (not frame
) t
)
383 (defun dont-constrain-if-too-much-aux (x y
)
384 (declare (optimize (speed 3) (safety 1) (debug 1)))
385 (if x t
(if y t
(dont-constrain-if-too-much x y
))))
387 (with-test (:name
(if :constraint-propagation
:bug-120a
))
388 (assert (null (dont-constrain-if-too-much-aux nil nil
))))
390 ;;; TYPE-ERROR confusion ca. sbcl-0.7.7.24, reported and fixed by
391 ;;; APD sbcl-devel 2002-09-14
392 (defun exercise-0-7-7-24-bug (x)
393 (declare (integer x
))
395 (setf y
(the single-float
(if (> x
0) x
3f0
)))
397 (with-test (:name
(type-error :0.7.7.24))
398 (assert-error (exercise-0-7-7-24-bug 4) type-error
)
399 (assert (equal (exercise-0-7-7-24-bug -
4) '(3f0 3f0
))))
401 ;;; non-intersecting type declarations were DWIMing in a confusing
402 ;;; fashion until sbcl-0.7.7.28, when APD reported and fixed the
404 (defun non-intersecting-the (x)
406 (setf y
(the single-float
(the integer x
)))
409 (with-test (:name
:non-intersecting-the
)
410 (assert-error (non-intersecting-the 3) type-error
)
411 (assert-error (non-intersecting-the 3f0
) type-error
))
413 ;;; until 0.8.2 SBCL did not check THEs in arguments
414 (defun the-in-arguments-aux (x)
416 (defun the-in-arguments-1 (x)
417 (list x
(the-in-arguments-aux (the (single-float 0s0
) x
))))
418 (defun the-in-arguments-2 (x)
419 (list x
(the-in-arguments-aux (the single-float x
))))
421 (with-test (:name
(the :argument
))
422 (assert-error (the-in-arguments-1 1) type-error
)
423 (assert-error (the-in-arguments-2 1) type-error
))
425 ;;; bug 153: a hole in a structure slot type checking
426 (declaim (optimize safety
))
428 (bla 0 :type fixnum
))
430 (let ((foo (make-foo153)))
431 (setf (foo153-bla foo
) '(1 .
1))
432 (format t
"Is ~a of type ~a a cons? => ~a~%"
434 (type-of (foo153-bla foo
))
435 (consp (foo153-bla foo
)))))
437 (let ((foo (make-foo153)))
438 (setf (foo153-bla foo
) x
)
439 (format t
"Is ~a of type ~a a cons? => ~a~%"
441 (type-of (foo153-bla foo
))
442 (consp (foo153-bla foo
)))))
444 (with-test (:name
(:name defstruct
:slot
:type
:bug-153
))
445 (assert-error (bug153-1) type-error
)
446 (assert-error (bug153-2 '(1 .
1)) type-error
))
448 ;;;; bug 110: the compiler flushed the argument type test and the default
449 ;;;; case in the cond.
451 ;(locally (declare (optimize (safety 3) (speed 2)))
453 ; (declare (optimize (safety 2) (speed 3)))
454 ; (declare (type (or string stream) x))
455 ; (cond ((typep x 'string) 'string)
456 ; ((typep x 'stream) 'stream)
460 ;(multiple-value-bind (result condition)
461 ; (ignore-errors (bug110 0))
462 ; (declare (ignore result))
463 ; (assert (typep condition 'type-error)))
465 ;;; bug 202: the compiler failed to compile a function, which derived
466 ;;; type contradicted declared.
467 (declaim (ftype (function () null
) bug202
))
471 ;;; bugs 178, 199: compiler failed to compile a call of a function
472 ;;; with a hairy type
474 (funcall (the function
(the standard-object x
))))
476 (defun bug199-aux (f)
477 (eq nil
(funcall f
)))
480 (declare (type (and function
(satisfies bug199-aux
)) f
))
483 (with-test (:name
(declaim &optional
&rest
:bogus style-warning
))
486 "(declaim (ftype (function (symbol &optional t &rest t)) foo))
487 (defun foo (x &optional y &rest z)
488 (declare (ignore x y z)))"
492 ;;; check non-toplevel DEFMACRO
493 (defvar *defmacro-test-status
* nil
)
495 (with-test (:name
(compile-file defmacro
))
496 (fmakunbound 'defmacro-test-aux
)
497 (let* ((src "defmacro-test.lisp")
498 (obj (compile-file-pathname src
)))
502 (assert (equal *defmacro-test-status
* '(function a
)))
503 (setq *defmacro-test-status
* nil
)
505 (assert (equal *defmacro-test-status
* nil
))
506 (macroexpand '(defmacro-test-aux 'a
))
507 (assert (equal *defmacro-test-status
* '(macro 'a z-value
)))
508 (eval '(defmacro-test-aux 'a
))
509 (assert (equal *defmacro-test-status
* '(expanded 'a z-value
))))
510 (ignore-errors (delete-file obj
)))))
512 ;;; bug 204: EVAL-WHEN inside a local environment
513 (defvar *bug204-test-status
*)
515 (with-test (:name
(compile-file eval-when
:local-environment
:bug-204
))
516 (let* ((src "bug204-test.lisp")
517 (obj (compile-file-pathname src
)))
520 (setq *bug204-test-status
* nil
)
521 (compile-file src
:verbose nil
:print nil
)
522 (assert (equal *bug204-test-status
* '((:expanded
:load-toplevel
)
523 (:called
:compile-toplevel
)
524 (:expanded
:compile-toplevel
))))
525 (setq *bug204-test-status
* nil
)
527 (assert (equal *bug204-test-status
* '((:called
:load-toplevel
)))))
528 (ignore-errors (delete-file obj
)))))
530 ;;; toplevel SYMBOL-MACROLET
531 ;;; FIXME: I didn't look into why this fails in the interpreter, but it does.
532 (defvar *symbol-macrolet-test-status
*)
534 (with-test (:name
(compile-file symbol-macrolet
) :skipped-on
:interpreter
)
535 (let* ((src "symbol-macrolet-test.lisp")
536 (obj (compile-file-pathname src
)))
539 (setq *symbol-macrolet-test-status
* nil
)
540 (compile-file src
:verbose nil
:print nil
)
541 (assert (equal *symbol-macrolet-test-status
*
543 (setq *symbol-macrolet-test-status
* nil
)
545 (assert (equal *symbol-macrolet-test-status
* '(2))))
546 (ignore-errors (delete-file obj
)))))
548 ;;; On the x86, this code failed to compile until sbcl-0.7.8.37:
549 (defun x86-assembler-failure (x)
550 (declare (optimize (speed 3) (safety 0)))
551 (eq (setf (car x
) 'a
) nil
))
553 ;;; bug 211: :ALLOW-OTHER-KEYS
554 (defun bug211d (&key
(x :x x-p
) ((:allow-other-keys y
) :y y-p
))
557 (with-test (:name
(:allow-other-keys
:bug-211d
))
558 (assert (equal (bug211d) '(:x nil
:y nil
)))
559 (assert (equal (bug211d :x
1) '(1 t
:y nil
)))
560 (assert-error (bug211d :y
2) program-error
)
561 (assert (equal (bug211d :y
2 :allow-other-keys t
:allow-other-keys nil
)
563 (assert-error (bug211d :y
2 :allow-other-keys nil
) program-error
))
567 (flet ((test (&key
(x :x x-p
) ((:allow-other-keys y
) :y y-p
))
569 (assert (equal (test) '(:x nil
:y nil
)))
570 (assert (equal (test :x
1) '(1 t
:y nil
)))
571 (assert (equal (test :y
2 :allow-other-keys
11 :allow-other-keys nil
)
574 (with-test (:name
(compile :lambda-list
:bug-211b
))
577 (with-test (:name
(compile :lambda-list
:bug-211c
))
578 (checked-compile-and-assert ()
580 (flet ((test (&key
(x :x x-p
))
582 (assert (equal (test) '(:x nil
)))
583 (assert (equal (test :x
1) '(1 t
)))
584 (assert (equal (test :y
2 :allow-other-keys
11 :allow-other-keys nil
)
589 (with-test (:name
(compile :lambda-list
:allow-other-keys
590 :bug-211
:do-not-allow
))
591 (dolist (form '((test :y
2)
592 (test :y
2 :allow-other-keys nil
)
593 (test :y
2 :allow-other-keys nil
:allow-other-keys t
)))
594 (multiple-value-bind (result failure-p
)
597 (flet ((test (&key
(x :x x-p
) ((:allow-other-keys y
) :y y-p
))
600 :allow-failure t
:allow-warnings t
)
602 (assert-error (funcall result
) program-error
))))
604 ;;; bug 217: wrong type inference
605 (defun bug217-1 (x s
)
606 (let ((f (etypecase x
607 (character #'write-char
)
608 (integer #'write-byte
))))
611 (character (write-char x s
))
612 (integer (write-byte x s
)))))
613 (with-test (:name
(:bug-217
))
614 (bug217-1 #\
1 (make-broadcast-stream)))
616 ;;; bug 221: tried and died on CSUBTYPEP (not VALUES-SUBTYPEP) of the
617 ;;; function return types when inferring the type of the IF expression
618 (declaim (ftype (function (fixnum) (values package boolean
)) bug221f1
))
619 (declaim (ftype (function (t) (values package boolean
)) bug221f2
))
621 (funcall (if b
#'bug221f1
#'bug221f2
) x
))
623 ;;; bug 172: macro lambda lists were too permissive until 0.7.9.28
624 ;;; (fix provided by Matthew Danish) on sbcl-devel
625 (with-test (:name
(defmacro :lambda-list
:bug-172
))
626 (assert-error (defmacro bug172
(&rest rest foo
) `(list ,rest
,foo
))))
628 (with-test (:name
(compile :embedded the
))
629 (flet ((check-embedded-thes (policy1 policy2 x y
)
631 (funcall (checked-compile
633 (declare (optimize (speed 2) (safety ,policy1
)))
635 (the (values (integer 2 3) t
&optional
)
636 (locally (declare (optimize (safety ,policy2
)))
637 (the (values t
(single-float 2f0
3f0
) &optional
)
639 (lambda () (values x y
)))
643 (assert (equal (check-embedded-thes 0 0 :a
:b
) '(:a
:b
)))
645 (assert (equal (check-embedded-thes 0 3 :a
2.5f0
) '(:a
2.5f0
)))
646 (assert (typep (check-embedded-thes 0 3 2 3.5f0
) 'type-error
))
648 (assert (equal (check-embedded-thes 0 1 :a
3.5f0
) '(:a
3.5f0
)))
649 (assert (typep (check-embedded-thes 0 1 2 2.5d0
) 'type-error
))
651 (assert (equal (check-embedded-thes 3 0 2 :a
) '(2 :a
)))
652 (assert (typep (check-embedded-thes 3 0 4 2.5f0
) 'type-error
))
654 (assert (equal (check-embedded-thes 1 0 3 :b
) '(3 :b
)))
655 (assert (typep (check-embedded-thes 1 0 1.0 2.5f0
) 'type-error
))
658 (assert (equal (check-embedded-thes 3 3 2 2.5f0
) '(2 2.5f0
)))
659 (assert (typep (check-embedded-thes 3 3 0 2.5f0
) 'type-error
))
660 (assert (typep (check-embedded-thes 3 3 2 3.5f0
) 'type-error
))))
663 ;;; INLINE inside MACROLET
664 (declaim (inline to-be-inlined
))
665 (macrolet ((def (x) `(defun ,x
(y) (+ y
1))))
667 (defun call-inlined (z)
669 (assert (= (call-inlined 3) 4))
670 (macrolet ((frob (x) `(+ ,x
3)))
671 (defun to-be-inlined (y)
674 (assert (= (call-inlined 3)
675 ;; we should have inlined the previous definition, so the
676 ;; new one won't show up yet.
678 (defun call-inlined (z)
680 #-interpreter
(assert (= (call-inlined 3) 6))
681 (defun to-be-inlined (y)
683 #-interpreter
(assert (= (call-inlined 3) 6))
685 ;;; DEFINE-COMPILER-MACRO to work as expected, not via weird magical
686 ;;; IR1 pseudo-:COMPILE-TOPLEVEL handling
687 (defvar *bug219-a-expanded-p
* nil
)
690 (define-compiler-macro bug219-a
(&whole form y
)
691 (setf *bug219-a-expanded-p
* t
)
695 (defun bug219-a-aux ()
697 (defvar *bug219-a-temp
* 3)
698 (with-test (:name
(define-compiler-macro :bug-219a
))
699 (assert (= (bug219-a-aux) (if *bug219-a-expanded-p
* 4 3)))
700 (assert (= (bug219-a *bug219-a-temp
*) 4)))
702 (defvar *bug219-b-expanded-p
* nil
)
703 (defun bug219-b-aux1 (x)
705 (define-compiler-macro bug219-b
(y)
706 (setf *bug219-b-expanded-p
* t
)
708 (defun bug219-b-aux2 (z)
710 (assert (not *bug219-b-expanded-p
*))
711 (assert-error (bug219-b-aux2 1) undefined-function
)
713 (defun bug219-b-aux2 (z)
717 (assert (= (bug219-b-aux2 1)
718 (if *bug219-b-expanded-p
* 3 1)))
720 (with-test (:name
(:unreachable-code locally declare
:bug-224
))
721 (map-optimize-declarations
722 (lambda (declaration)
723 (multiple-value-bind (fun failure-p warnings style-warnings
)
726 (declare (optimize ,@declaration
))
727 (,(gensym "LOCALY") (declare (optimize (safety 3)))
728 (ignore-errors (progn (values-list (car (list '(1 .
2)))) t
))))
729 :allow-failure t
:allow-style-warnings t
)
730 (declare (ignore fun warnings
))
732 (assert (= (length style-warnings
) 1))))
735 (with-test (:name
(:unreachable-code error labels
:bug-224
))
736 (map-optimize-declarations
737 (lambda (declaration)
738 (checked-compile `(lambda ()
739 (declare (optimize ,@declaration
))
742 (labels ((i1 () (list (i2) (i2)))
743 (i2 () (list (int) (i1)))
745 (list (i1) (i1) (i1)))
746 :exit
(return-from ext
))))
747 (list (error "nih") (ext) (ext))))))
750 (with-test (:name
(:unreachable-code error let
:bug-224
))
751 (map-optimize-declarations
752 (lambda (declaration)
753 (checked-compile `(lambda (x)
754 (declare (optimize ,@declaration
))
755 (let ((y (error ""))) (list x y
)))))
758 ;;; bug 223: invalid moving of global function name referencing
759 (defun bug223-int (n)
762 (defun bug223-wrap ()
763 (let ((old #'bug223-int
))
764 (setf (fdefinition 'bug223-int
)
767 `(ext ,@(funcall old
(1- n
)))))))
769 (with-test (:name
(compile setf fdefinition
:bug-223
))
770 (compile 'bug223-wrap
)
771 (assert (equal (bug223-int 4) '(int 4)))
773 (assert (equal (bug223-int 4) '(ext int
3)))
775 (assert (equal (bug223-int 4) '(ext ext int
2))))
777 ;;; COERCE got its own DEFOPTIMIZER which has to reimplement most of
778 ;;; SPECIFIER-TYPE-NTH-ARG. For a while, an illegal type would throw
779 ;;; you into the debugger on compilation.
780 (defun coerce-defopt1 (x)
781 ;; illegal, but should be compilable.
782 (coerce x
'(values t
)))
783 (defun coerce-defopt2 (x)
784 ;; illegal, but should be compilable.
785 (coerce x
'(values t
&optional
)))
786 (with-test (:name
(coerce :optimizer
))
787 (assert-error (coerce-defopt1 3))
788 (assert-error (coerce-defopt2 3)))
790 ;;; Oops. In part of the (CATCH ..) implementation of DEBUG-RETURN,
791 ;;; it was possible to confuse the type deriver of the compiler
792 ;;; sufficiently that compiler invariants were broken (explained by
793 ;;; APD sbcl-devel 2003-01-11).
795 ;;; WHN's original report
796 (defun debug-return-catch-break1 ()
797 (with-open-file (s "/tmp/foo"
802 (integer-length most-positive-fixnum
))))
808 ;;; APD's simplified test case
809 (defun debug-return-catch-break2 (x)
810 (declare (type (vector (unsigned-byte 8)) x
))
811 (setq *y
* (the (unsigned-byte 8) (aref x
4))))
813 ;;; FUNCTION-LAMBDA-EXPRESSION should return something that COMPILE
814 ;;; can understand. Here's a simple test for that on a function
815 ;;; that's likely to return a hairier list than just a lambda:
816 (macrolet ((def (fn) `(progn
817 (declaim (inline ,fn
))
818 (defun ,fn
(x) (1+ x
)))))
820 (with-test (:name
(function-lambda-expression compile
:bug-228
))
821 (let ((x (function-lambda-expression #'bug228
)))
823 (checked-compile-and-assert (:optimize nil
) x
829 (declare (type (mod 4) i
))
832 (with-test (:name
:bug-192b
)
833 (assert-error (bug192b 6) type-error
))
836 (locally (declare (type fixnum x y
))
838 (with-test (:name
:bug-192c
)
839 (assert-error (bug192c 1.1 2) type-error
)
840 (assert-error (progn (the real
(list 1)) t
) type-error
))
843 (declare (optimize (speed 2) (safety 0)))
846 (multiple-value-prog1
848 (unless f
(return-from bug236
0))))))
849 (with-test (:name
:bug-236
)
850 (assert (eql (bug236 #(4) nil
) 0)))
852 ;;; Bug reported by reported by rif on c.l.l 2003-03-05
853 (defun test-type-of-special-1 (x)
856 (optimize (safety 3)))
858 (defun test-type-of-special-2 (x)
861 (optimize (safety 3)))
862 (list x
(setq x
(/ x
2)) x
))
863 (with-test (:name
(declare special type
))
864 (assert-error (test-type-of-special-1 3/2) type-error
)
865 (assert-error (test-type-of-special-2 3) type-error
)
866 (assert (equal (test-type-of-special-2 8) '(8 4 4))))
868 ;;; bug which existed in 0.8alpha.0.4 for several milliseconds before
869 ;;; APD fixed it in 0.8alpha.0.5
870 (defun frob8alpha04 (x y
)
872 (defun baz8alpha04 (this kids
)
873 (flet ((n-i (&rest rest
)
874 ;; Removing the #+NIL here makes the bug go away.
875 #+nil
(format t
"~&in N-I REST=~S~%" rest
)
876 (apply #'frob8alpha04 this rest
)))
878 ;;; failed in 0.8alpha.0.4 with "The value 13 is not of type LIST."
879 (with-test (:name
(&rest type-error
))
880 (assert (= (baz8alpha04 12 13) 25)))
882 ;;; evaluation order in structure slot writers
885 (with-test (:name
(:evaluation-order structure
:slot-writer
))
887 (s (make-sswo :a
(incf i
) :b
(incf i
)))
889 (assert (= (sswo-a s
) 1))
890 (assert (= (sswo-b s
) 2))
891 (setf (sswo-a (pop l
)) (pop l
))
893 (assert (eq (sswo-a s
) :v
))))
899 (list (bar x
) (bar x
) (bar x
))))
901 (with-test (:name
(flet declare type
:bug-249
))
902 (assert-error (bug249 1.0) type-error
))
904 ;;; bug reported by ohler on #lisp 2003-07-10
905 (defun bug-ohler-2003-07-10 (a b
)
906 (declare (optimize (speed 0) (safety 3) (space 0)
907 (debug 1) (compilation-speed 0)))
910 ;;; bug reported by Doug McNaught on sbcl-devel 2003-09-14:
911 ;;; COMPILE-FILE did not bind *READTABLE*
912 (with-test (:name
(compile-file *readtable
*))
913 (let* ((source "bug-doug-mcnaught-20030914.lisp")
914 (fasl (compile-file-pathname source
)))
916 (assert (null (get-macro-character #\
]))))
919 (assert (typep *bug-doug-mcnaught-20030914
*
920 '(simple-array (unsigned-byte 4) (*))))
921 (assert (equalp *bug-doug-mcnaught-20030914
* #(1 2 3)))
922 (makunbound '*bug-doug-mcnaught-20030914
*)))
923 (compile-file source
)
929 (delete-file fasl
))))
931 (defun expt-derive-type-bug (a b
)
933 (truncate (expt a b
))))
934 (with-test (:name
(expt :derive-type
))
935 (assert (equal (multiple-value-list (expt-derive-type-bug 1 1))
938 ;;; Problems with type checking in functions with EXPLICIT-CHECK
939 ;;; attribute (reported by Peter Graves)
940 (with-test (:name
(:type-checking
:explicit-check
))
941 (loop for
(fun . args
) in
'((= a
) (/= a
)
942 (< a
) (<= a
) (> a
) (>= a
))
943 do
(assert-error (apply fun args
) type-error
)))
945 (defclass broken-input-stream
(sb-gray:fundamental-input-stream
) ())
946 (defmethod sb-gray:stream-read-char
((stream broken-input-stream
))
947 (throw 'break
:broken
))
948 (with-test (:name
:explicit-check
)
949 (assert (eql (block return
952 (funcall (eval ''peek-char
)
953 1 (make-instance 'broken-input-stream
))
957 (return-from return
:good
))))
960 ;;;; MUFFLE-CONDITIONS test (corresponds to the test in the manual)
961 ; FIXME: make a better test!
962 (with-test (:name muffle-conditions
:skipped-on
(or :alpha
:x86-64
))
963 (multiple-value-bind (fun failure-p warnings style-warnings notes
)
966 (declare (optimize speed
) (fixnum x
))
967 (declare (sb-ext:muffle-conditions sb-ext
:compiler-note
))
968 (values (* x
5) ; no compiler note from this
970 (declare (sb-ext:unmuffle-conditions sb-ext
:compiler-note
))
971 ;; this one gives a compiler note
973 (declare (ignore failure-p warnings
))
974 (assert (= (length notes
) 1))
975 (assert (equal (multiple-value-list (funcall fun
1)) '(5 -
5)))))
977 (with-test (:name
(flet labels
&key
))
978 (assert-error (eval '(flet ((%f
(&key
) nil
)) (%f nil nil
))))
979 (assert-error (eval '(labels ((%f
(&key x
) x
)) (%f nil nil
)))))
981 ;;; PROGV must not bind constants, or violate declared types -- ditto for SET.
982 (assert-error (set pi
3))
983 (assert-error (progv '(pi s
) '(3 pi
) (symbol-value x
)))
984 (declaim (cons *special-cons
*))
985 (assert-error (set '*special-cons
* "nope") type-error
)
986 (assert-error (progv '(*special-cons
*) '("no hope") (car *special-cons
*)) type-error
)
988 ;;; No bogus warnings for calls to functions with complex lambda-lists.
989 (defun complex-function-signature (&optional x
&rest y
&key z1 z2
)
990 (declare (ignore z1 z2
))
992 (with-test (:name
:complex-call-doesnt-warn
)
993 (checked-compile '(lambda (x) (complex-function-signature x
:z1
1 :z2
2))))
995 (with-test (:name
:non-required-args-update-info
)
996 (let ((name (gensym "NON-REQUIRE-ARGS-TEST"))
997 (*evaluator-mode
* :compile
))
998 (eval `(defun ,name
(x) x
))
999 (assert (equal '(function (t) (values t
&optional
))
1000 (sb-kernel:type-specifier
(sb-int:proclaimed-ftype name
))))
1001 (eval `(defun ,name
(x &optional y
) (or x y
)))
1002 (assert (equal '(function (t &optional t
) (values t
&optional
))
1003 (sb-kernel:type-specifier
(sb-int:proclaimed-ftype name
))))))
1005 ;;;; inline & maybe inline nested calls
1007 (defun quux-marker (x) x
)
1008 (declaim (inline foo-inline
))
1009 (defun foo-inline (x) (quux-marker x
))
1010 (declaim (maybe-inline foo-maybe-inline
))
1011 (defun foo-maybe-inline (x) (quux-marker x
))
1013 (with-test (:name
:nested-inline-calls
)
1014 (let ((fun (checked-compile `(lambda (x)
1015 (foo-inline (foo-inline (foo-inline x
)))))))
1016 (assert (= 0 (ctu:count-full-calls
"FOO-INLINE" fun
)))
1017 (assert (= 3 (ctu:count-full-calls
"QUUX-MARKER" fun
)))))
1019 (with-test (:name
:nested-maybe-inline-calls
)
1020 (let ((fun (checked-compile
1022 (declare (optimize (space 0)))
1023 (foo-maybe-inline (foo-maybe-inline (foo-maybe-inline x
)))))))
1024 (assert (= 0 (ctu:count-full-calls
"FOO-MAYBE-INLINE" fun
)))
1025 (assert (= 1 (ctu:count-full-calls
"QUUX-MARKER" fun
)))))
1027 (with-test (:name
:inline-calls
)
1028 (let ((fun (checked-compile `(lambda (x)
1029 (list (foo-inline x
)
1032 (assert (= 0 (ctu:count-full-calls
"FOO-INLINE" fun
)))
1033 (assert (= 3 (ctu:count-full-calls
"QUUX-MARKER" fun
)))))
1035 (with-test (:name
:maybe-inline-calls
)
1036 (let ((fun (checked-compile `(lambda (x)
1037 (declare (optimize (space 0)))
1038 (list (foo-maybe-inline x
)
1039 (foo-maybe-inline x
)
1040 (foo-maybe-inline x
))))))
1041 (assert (= 0 (ctu:count-full-calls
"FOO-MAYBE-INLINE" fun
)))
1042 (assert (= 1 (ctu:count-full-calls
"QUUX-MARKER" fun
)))))
1044 (with-test (:name
:bug-405
)
1045 ;; These used to break with a TYPE-ERROR
1046 ;; The value NIL is not of type SB-C::PHYSENV.
1049 '((LET (outer-let-var)
1051 (print outer-let-var
)
1052 (MULTIPLE-VALUE-CALL 'some-function
1053 (MULTIPLE-VALUE-CALL (LAMBDA (a) 'foo
)
1056 '((declaim (optimize (debug 3)))
1057 (defstruct bug-405-foo bar
)
1059 (flet ((i (x) (frob x
(bug-405-foo-bar foo
))))
1063 (declaim (ftype (function (cons) number
) bug-235a-aux
))
1064 (declaim (inline bug-235a-aux
))
1065 (defun bug-235a-aux (c)
1066 (the number
(car c
)))
1067 (with-test (:name
:bug-235a
)
1068 (let ((fun (checked-compile
1070 (values (locally (declare (optimize (safety 0)))
1072 (locally (declare (optimize (safety 3)))
1073 (bug-235a-aux y
)))))))
1077 (funcall fun
'(:one
) '(:two
))
1079 (assert (eq :two
(type-error-datum e
)))
1080 (assert (eq 'number
(type-error-expected-type e
)))
1083 (with-test (:name
:compiled-debug-funs-leak
)
1085 (let ((usage-before (sb-kernel::dynamic-usage
)))
1087 (let ((f (checked-compile '(lambda () (error "X")))))
1092 (let ((usage-after (sb-kernel::dynamic-usage
)))
1093 (when (< (+ usage-before
2000000) usage-after
)
1096 ;;; PROGV compilation and type checking when the declared type
1097 ;;; includes a FUNCTION subtype.
1098 (declaim (type (or (function (t) (values boolean
&optional
)) string
)
1100 (defvar *hairy-progv-var
* #'null
)
1101 (with-test (:name
:hairy-progv-type-checking
)
1104 (progv '(*hairy-progv-var
*) (list (eval 42))
1106 (type-error () :error
))))
1107 (assert (equal "GOOD!"
1108 (progv '(*hairy-progv-var
*) (list (eval "GOOD!"))
1109 *hairy-progv-var
*))))
1111 (with-test (:name
:fill-complex-single-float
)
1112 (assert (every (lambda (x) (eql x
#c
(-1.0 -
2.0)))
1116 :element-type
'(complex single-float
)
1117 :initial-element
#c
(-1.0 -
2.0)))))))
1119 (with-test (:name
:make-array-symbol-as-initial-element
)
1120 (checked-compile-and-assert ()
1122 (make-array 12 :initial-element
'a
))
1123 (() #(a a a a a a a a a a a a
) :test
'equalp
)))
1125 ;;; This non-minimal test-case catches a nasty error when loading
1126 ;;; inline constants.
1128 `(simple-array single-float
(16)))
1129 (declaim (ftype (sb-int:sfunction
(single-float single-float single-float single-float
1130 single-float single-float single-float single-float
1131 single-float single-float single-float single-float
1132 single-float single-float single-float single-float
)
1136 (defun matrix (m11 m12 m13 m14
1141 :element-type
'single-float
1142 :initial-contents
(list m11 m21 m31 m41
1146 (declaim (ftype (sb-int:sfunction
((simple-array single-float
(3)) single-float
) matrix
)
1148 (defun rotate-around (a radians
)
1149 (let ((c (cos radians
))
1151 ;; The 1.0 here was misloaded on x86-64.
1152 (g (- 1.0 (cos radians
))))
1153 (let* ((x (aref a
0))
1156 (gxx (* g x x
)) (gxy (* g x y
)) (gxz (* g x z
))
1157 (gyy (* g y y
)) (gyz (* g y z
)) (gzz (* g z z
)))
1159 (+ gxx c
) (- gxy
(* s z
)) (+ gxz
(* s y
)) 0.0
1160 (+ gxy
(* s z
)) (+ gyy c
) (- gyz
(* s x
)) 0.0
1161 (- gxz
(* s y
)) (+ gyz
(* s x
)) (+ gzz c
) 0.0
1163 (with-test (:name
:regression-1.0
.29.54)
1165 '(-1.0
0.0 0.0 0.0 0.0 -
1.0 0.0 0.0 0.0 0.0 -
1.0 0.0 0.0 0.0 0.0 1.0)
1167 (make-array 3 :element-type
'single-float
) (coerce pi
'single-float
))))
1168 ;; Same bug manifests in COMPLEX-ATANH as well.
1169 (assert (= (atanh #C
(-0.7d0
1.1d0
)) #C
(-0.28715567731069275d0
0.9394245539093365d0
))))
1171 (with-test (:name
:slot-value-on-structure
)
1172 (let ((f (checked-compile `(lambda (x a b
)
1173 (declare (something-known-to-be-a-struct x
))
1174 (setf (slot-value x
'x
) a
1175 (slot-value x
'y
) b
)
1176 (list (slot-value x
'x
)
1177 (slot-value x
'y
))))))
1178 (assert (equal '(#\x
#\y
)
1180 (make-something-known-to-be-a-struct :x
"X" :y
"Y")
1182 (assert (not (ctu:find-named-callees f
)))))
1184 (defclass some-slot-thing
()
1185 ((slot :initarg
:slot
)))
1186 (with-test (:name
:with-slots-the
)
1187 (let ((x (make-instance 'some-slot-thing
:slot
"foo")))
1188 (with-slots (slot) (the some-slot-thing x
)
1189 (assert (equal "foo" slot
)))))
1191 ;;; Missing &REST type in proclamation causing a miscompile.
1194 (sequence unsigned-byte
1195 &key
(:initial-element t
) (:initial-contents sequence
))
1196 (values sequence
&optional
))
1201 &key
(initial-element nil iep
) (initial-contents nil icp
))
1202 (declare (sb-ext:unmuffle-conditions style-warning
))
1203 (declare (ignorable keys initial-element iep initial-contents icp
))
1204 (apply #'sb-sequence
:make-sequence-like sequence length keys
))
1205 (with-test (:name
:bug-458354
)
1206 (assert (equalp #((a b
) (a b
)) (bug-458354 #(1 2) 2 :initial-element
'(a b
)))))
1208 (with-test (:name
:bug-542807
)
1209 (handler-bind ((style-warning #'error
))
1210 (eval '(defstruct bug-542807 slot
)))
1212 (handler-bind ((style-warning (lambda (c)
1214 (eval '(defstruct bug-542807 slot
)))
1216 (every (lambda (x) (typep x
'sb-kernel
:redefinition-with-defun
))
1219 (with-test (:name
:defmacro-not-list-lambda-list
)
1220 (assert-error (eval `(defmacro ,(gensym) "foo"))
1223 (with-test (:name
:bug-308951
)
1227 (when (funcall (eval #'(lambda (x) (eql x
2))) y
)
1228 (defun bug-308951-foo (z)
1229 (incf x
(incf y z
))))))
1230 (defun bug-308951-bar (z)
1233 (assert (= 4 (bug-308951-bar 1))))
1235 (declaim (inline bug-308914-storage
))
1236 (defun bug-308914-storage (x)
1237 (the (simple-array flt
(*)) (bug-308914-unknown x
)))
1239 (with-test (:name
:bug-308914-workaround
)
1240 ;; This used to hang in ORDER-UVL-SETS.
1244 `(lambda (lumps &key cg
)
1245 (let ((nodes (map 'list
(lambda (lump)
1246 (bug-308914-storage lump
))
1248 (setf (aref nodes
0) 2)
1249 (assert (every #'~
= (apply #'concatenate
'list nodes
) '(2 3 6 9)))))
1250 :allow-warnings t
:allow-style-warnings t
))
1252 (error "Hang in ORDER-UVL-SETS?"))))
1254 (declaim (inline inlined-function-in-source-path
))
1255 (defun inlined-function-in-source-path (x)
1258 (with-test (:name
:inlined-function-in-source-path
)
1260 (with-output-to-string (*error-output
*)
1261 (compile nil
`(lambda (x)
1262 (declare (optimize speed
))
1263 (funcall #'inlined-function-in-source-path x
))))))
1265 (assert (search "INLINED-FUNCTION-IN-SOURCE-PATH" output
))
1267 (assert (not (search "DEFINED-FUN" output
)))))
1269 (defmacro bug-795705
()
1272 (with-test (:name
:bug-795705
)
1273 (assert (macro-function 'bug-795705
))
1274 (fmakunbound 'bug-795705
)
1275 (assert (not (macro-function 'bug-795705
))))
1277 (with-test (:name
(load-time-value :type-derivation
))
1278 (let ((name 'load-time-value-type-derivation-test
))
1279 (labels ((funtype (fun)
1280 (sb-kernel:type-specifier
1281 (sb-kernel:single-value-type
1282 (sb-kernel:fun-type-returns
1283 (sb-kernel:specifier-type
1284 (sb-kernel:%simple-fun-type fun
))))))
1285 (test (type1 type2 form value-cell-p
)
1286 (declare (ignore value-cell-p
))
1287 (let* ((lambda-form `(lambda ()
1288 (load-time-value ,form
)))
1289 (core-fun (checked-compile lambda-form
))
1290 (core-type (funtype core-fun
))
1291 (defun-form `(defun ,name
()
1292 (load-time-value ,form
)))
1293 (file-fun (let ((*error-output
* (make-broadcast-stream)))
1294 (ctu:file-compile
(list defun-form
) :load t
)
1295 (symbol-function name
)))
1296 (file-type (funtype file-fun
)))
1297 (unless (subtypep core-type type1
)
1298 (error "core: wanted ~S, got ~S" type1 core-type
))
1299 (unless (subtypep file-type type2
)
1300 (error "file: wanted ~S, got ~S" type2 file-type
)))))
1302 (test '(integer 11 11) 'number
1305 (test '(integer 4 4) 'unsigned-byte
1307 (test '(integer 10 10) '(integer 10 10) 10 nil
)
1308 (test 'cons
'cons
'(cons t t
) t
))))
1310 (with-test (:name
(load-time-value :errors
))
1311 (multiple-value-bind (warn fail
)
1313 `((defvar *load-time-value-error-value
* 10)
1314 (declaim (fixnum *load-time-value-error-value
*))
1315 (defun load-time-value-error-test-1 ()
1316 (the list
(load-time-value *load-time-value-error-value
*))))
1320 (handler-case (load-time-value-error-test-1)
1322 (and (eql 10 (type-error-datum e
))
1323 (eql 'list
(type-error-expected-type e
)))))
1324 (multiple-value-bind (warn2 fail2
)
1326 `((defun load-time-value-error-test-2 ()
1327 (the list
(load-time-value 10))))
1331 (handler-case (load-time-value-error-test-2)
1333 (and (eql 10 (type-error-datum e
))
1334 (eql 'list
(type-error-expected-type e
))))))
1336 ;;;; tests for compiler output
1337 (with-test (:name
:unexpected-compiler-output
)
1338 (let* ((*error-output
* (make-string-output-stream))
1339 (output (with-output-to-string (*standard-output
*)
1340 (compile-file "compiler-output-test.lisp"
1341 :print nil
:verbose nil
))))
1342 (unless (zerop (length output
))
1343 (error "Unexpected output: ~S" output
))))
1345 (with-test (:name
:bug-493380
)
1346 (flet ((test (forms)
1348 (let ((*debugger-hook
* (lambda (condition if
)
1349 (declare (ignore if
))
1351 (if (typep condition
'serious-condition
)
1354 (multiple-value-bind (warned failed
) (ctu:file-compile forms
)
1355 (when (and warned failed
)
1357 (assert (eq :failed
(test "(defun")))
1358 (assert (eq :failed
(test "(defun no-pkg::foo ())")))
1359 (assert (eq :failed
(test "(cl:no-such-sym)")))
1360 (assert (eq :failed
(test "...")))))
1362 (defun cmacro-signals-error () :fun
)
1363 (define-compiler-macro cmacro-signals-error
() (error "oops"))
1365 (with-test (:name
:cmacro-signals-error
)
1366 (multiple-value-bind (fun failure-p warnings
)
1367 (checked-compile `(lambda () (cmacro-signals-error))
1368 :allow-failure t
:allow-warnings t
)
1369 (assert (and fun failure-p warnings
))
1370 (assert (eq :fun
(funcall fun
)))))
1372 (defun cmacro-with-simple-key (&key a
)
1373 (format nil
"fun=~A" a
))
1374 (define-compiler-macro cmacro-with-simple-key
(&whole form
&key a
)
1376 (format nil
"cmacro=~A" (eval a
))
1379 (with-test (:name
(:cmacro-with-simple-key
:no-key
))
1380 (checked-compile-and-assert ()
1381 `(lambda () (cmacro-with-simple-key))
1384 (with-test (:name
(:cmacro-with-simple-key
:constant-key
))
1385 (checked-compile-and-assert ()
1386 `(lambda () (cmacro-with-simple-key :a
42))
1389 (with-test (:name
(:cmacro-with-simple-key
:variable-key
))
1390 (checked-compile-and-assert ()
1391 `(lambda (x) (cmacro-with-simple-key x
42))
1394 (defun cmacro-with-nasty-key (&key
((nasty-key var
)))
1395 (format nil
"fun=~A" var
))
1396 (define-compiler-macro cmacro-with-nasty-key
(&whole form
&key
((nasty-key var
)))
1398 (format nil
"cmacro=~A" (eval var
))
1401 (with-test (:name
(:cmacro-with-nasty-key
:no-key
))
1402 (checked-compile-and-assert ()
1403 `(lambda () (cmacro-with-nasty-key))
1406 (with-test (:name
(:cmacro-with-nasty-key
:constant-key
))
1407 ;; This bogosity is thanks to cmacro lambda lists being /macro/ lambda
1409 (checked-compile-and-assert ()
1410 `(lambda () (cmacro-with-nasty-key 'nasty-key
42))
1413 (with-test (:name
(:cmacro-with-nasty-key
:variable-key
))
1414 (checked-compile-and-assert ()
1415 `(lambda (nasty-key) (cmacro-with-nasty-key nasty-key
42))
1416 (('nasty-key
) "fun=42")))
1418 (defconstant tricky-key
'tricky-key
)
1419 (defun cmacro-with-tricky-key (&key
((tricky-key var
)))
1420 (format nil
"fun=~A" var
))
1421 (define-compiler-macro cmacro-with-tricky-key
(&whole form
&key
((tricky-key var
)))
1423 (format nil
"cmacro=~A" (eval var
))
1426 (with-test (:name
(:cmacro-with-tricky-key
:no-key
))
1427 (let ((fun (checked-compile
1428 `(lambda () (cmacro-with-tricky-key)))))
1429 (assert (string= "cmacro=NIL" (funcall fun
)))))
1431 (with-test (:name
(:cmacro-with-tricky-key
:constant-quoted-key
))
1432 ;; This bogosity is thanks to cmacro lambda lists being /macro/ lambda
1434 (let ((fun (checked-compile
1435 `(lambda () (cmacro-with-tricky-key 'tricky-key
42)))))
1436 (assert (string= "fun=42" (funcall fun
)))))
1438 (with-test (:name
(:cmacro-with-tricky-key
:constant-unquoted-key
))
1439 (let ((fun (checked-compile
1440 `(lambda () (cmacro-with-tricky-key tricky-key
42)))))
1441 (assert (string= "cmacro=42" (funcall fun
)))))
1443 (with-test (:name
(:cmacro-with-tricky-key
:variable-key
))
1444 (let ((fun (checked-compile
1445 `(lambda (x) (cmacro-with-tricky-key x
42)))))
1446 (assert (string= "fun=42" (funcall fun
'tricky-key
)))))
1448 (defun test-function-983 (x) x
)
1449 (define-compiler-macro test-function-983
(x) x
)
1451 (with-test (:name
:funcall-compiler-macro
)
1456 (funcall (function test-function-983 junk
) 1)))
1458 (sb-c:compiler-error
() t
))))
1460 (defsetf test-984 %test-984
)
1462 (with-test (:name
:setf-function-with-setf-expander
)
1465 (and (defun (setf test-984
) ())
1467 (style-warning () t
)))
1468 (checked-compile `(lambda () #'(setf test-984
))
1469 :allow-style-warnings t
))
1471 (with-test (:name
:compile-setf-function
)
1472 (defun (setf compile-setf
) ())
1473 (assert (equal (compile '(setf compile-setf
))
1474 '(setf compile-setf
))))
1476 (declaim (inline cut-test
))
1478 (cond ((integerp b
) b
)
1482 (with-test (:name
:cut-to-width-bad-constant
)
1483 (assert (= (funcall (checked-compile
1485 (multiple-value-bind (a b
) (values t t
)
1486 (declare (ignore b
))
1487 (mask-field (byte 10 0) (cut-test a
))))))
1490 ;; META: there's a test in compiler.pure.lisp that also tests
1491 ;; interaction of PROGV with (debug 3). These tests should be together.
1492 (with-test (:name
:progv-debug-3
)
1494 (sb-ext:restrict-compiler-policy
'debug
3)
1495 (assert (funcall (checked-compile
1497 (declare (special *v
*))
1501 (sb-ext:restrict-compiler-policy
'debug
0)))
1503 (with-test (:name
:restrict-compiler-policy-result
)
1504 (let ((sb-c::*policy-min
* sb-c
::*policy-min
*)
1505 (sb-c::*policy-max
* sb-c
::*policy-max
*))
1506 (sb-ext:restrict-compiler-policy
'safety
2)
1507 (checked-compile '(lambda () (declare (optimize (safety 0))))))
1508 (let ((sb-c::*policy-min
* sb-c
::*policy-min
*)
1509 (sb-c::*policy-max
* sb-c
::*policy-max
*))
1510 ;; Passing no arguments returns the current quality/value pairs.
1511 (assert (null (sb-ext:restrict-compiler-policy
)))
1512 (let ((res (sb-ext:restrict-compiler-policy
'safety
2)))
1514 (assert (equal res
'((safety .
2)))))
1515 (let ((res (sb-ext:restrict-compiler-policy
'debug
3)))
1516 ;; returns an alist, indeterminate order
1517 (assert (or (equal res
'((safety .
2) (debug .
3)))
1518 (equal res
'((debug .
3) (safety .
2))))))
1519 ;; remove the SAFETY restriction
1520 (let ((res (sb-ext:restrict-compiler-policy
'safety
0)))
1521 (assert (equal res
'((debug .
3)))))
1522 ;; remove the DEBUG restriction
1523 (let ((res (sb-ext:restrict-compiler-policy
'debug
0)))
1524 (assert (null res
)))))
1526 ;;;; tests not in the problem domain, but of the consistency of the
1527 ;;;; compiler machinery itself
1531 ;;; Hunt for wrong-looking things in fundamental compiler definitions,
1532 ;;; and gripe about them.
1534 ;;; FIXME: It should be possible to (1) repair the things that this
1535 ;;; code gripes about, and then (2) make the code signal errors
1536 ;;; instead of just printing complaints to standard output, in order
1537 ;;; to prevent the code from later falling back into disrepair.
1538 (defun grovel-results (function)
1539 (dolist (template (fun-info-templates (info :function
:info function
)))
1540 (when (template-more-results-type template
)
1541 (format t
"~&Template ~A has :MORE results, and translates ~A.~%"
1542 (template-name template
)
1545 (when (eq (template-result-types template
) :conditional
)
1548 (let ((types (template-result-types template
))
1549 (result-type (fun-type-returns (proclaimed-ftype function
))))
1551 ((values-type-p result-type
)
1552 (do ((ltypes (append (args-type-required result-type
)
1553 (args-type-optional result-type
))
1555 (types types
(rest types
)))
1557 (unless (null types
)
1559 (format t
"~&More types than ltypes in ~A, translating ~A.~%"
1560 (template-name template
)
1564 (unless (null ltypes
)
1566 (format t
"~&More ltypes than types in ~A, translating ~A.~%"
1567 (template-name template
)
1570 ((eq result-type
(specifier-type nil
))
1571 (unless (null types
)
1572 (format t
"~&Template ~A returns values for function ~A with RESULT-TYPE NIL.~%"
1573 (template-name template
)
1576 ((/= (length types
) 1)
1577 (format t
"~&Template ~A isn't returning 1 value for ~A.~%"
1578 (template-name template
)
1582 (test-util:with-test
(:name
:identify-suspect-vops
)
1583 (sb-int:call-with-each-globaldb-name
1585 ;; LEGAL-FUN-NAME-P test is necessary, since (INFO :FUNCTION :TYPE)
1586 ;; has a defaulting expression that involves calling FDEFINITION.
1587 (when (and (legal-fun-name-p name
) (proclaimed-ftype name
))
1588 ;; OK, so we have an entry in the INFO database. Now, if ...
1589 (binding* ((info (info :function
:info name
) :exit-if-null
)
1590 (nil (fun-info-templates info
) :exit-if-null
))
1591 ;; ... it has translators
1592 (grovel-results name
))))))
1594 ;;;; bug 305: INLINE/NOTINLINE causing local ftype to be lost
1596 (test-util:with-test
(:name
(compile inline notinline
))
1597 (labels ((compile-lambda (type sense allow-notes
)
1599 4 (test-util:checked-compile
1602 ,@(when type
'((ftype (function () (integer 0 10)) bug-305
)))
1606 :allow-style-warnings t
:allow-notes allow-notes
))))
1607 (assert (compile-lambda nil
'inline t
))
1608 (assert (compile-lambda nil
'notinline t
))
1609 (compile-lambda t
'inline nil
)
1610 (compile-lambda t
'notinline nil
)))
1612 ;;; bug 211e: bogus style warning from duplicated keyword argument to
1613 ;;; a local function.
1614 (test-util:with-test
(:name
(compile flet
:duplicate
&key
:bug-211e
))
1615 (let ((f (test-util:checked-compile
1617 (flet ((foo (&key y
) (list y
)))
1618 (list (foo :y
1 :y
2)))))))
1619 (assert (equal '((1)) (funcall f
)))))
1621 ;;; check that EQL is optimized when other argument is (OR SYMBOL FIXNUM).
1622 (test-util:with-test
(:name
(compile :optimize eql
))
1623 (let ((f1 (test-util:checked-compile
1625 (declare (type (or symbol fixnum
) x1
)
1629 (f2 (test-util:checked-compile
1631 (declare (type (or symbol fixnum
) y2
)
1635 (let ((fix (random most-positive-fixnum
))
1638 (assert (funcall f1 fix fix
))
1639 (assert (funcall f2 fix fix
))
1640 (assert (funcall f1 sym sym
))
1641 (assert (funcall f2 sym sym
))
1642 (handler-bind ((type-error (lambda (c)
1645 (flet ((test (f x y
)
1646 (with-simple-restart (continue "continue with next test")
1648 (error "fell through with (~S ~S ~S)" f x y
))))
1650 (test f1
(1+ most-positive-fixnum
) 42)
1652 (test f2
42 (1+ most-positive-fixnum
))))
1653 (assert (= e-count
4)))))
1655 ;;; bug #389 (Rick Taube sbcl-devel)
1656 (declaim (ftype function bes-j0 bes-j1
))
1657 (defun bes-jn (unn ux
)
1658 (let ((nn unn
) (x ux
))
1659 (let* ((n (floor (abs nn
)))
1672 (do ((tox (/ 2.0 (abs x
)))
1673 (bjm (bes-j0 (abs x
)))
1674 (bj (bes-j1 (abs x
)))
1677 ((= j n
) (setf ans bj
))
1678 (setf bjp
(- (* j tox bj
) bjm
))
1681 (let ((tox (/ 2.0 (abs x
)))
1685 (/ (+ n
(sqrt (* iacc n
)))
1694 (setf bjm
(- (* j tox bj
) bjp
))
1697 (when (> (abs bj
) bigno
)
1698 (setf bj
(* bj bigni
))
1699 (setf bjp
(* bjp bigni
))
1700 (setf ans
(* ans bigni
))
1701 (setf sum
(* sum bigni
)))
1702 (if (not (= 0 jsum
)) (incf sum bj
))
1703 (setf jsum
(- 1 jsum
))
1704 (if (= j n
) (setf ans bjp
)))
1705 (setf sum
(- (* 2.0 sum
) bj
))
1706 (setf ans
(/ ans sum
))))
1707 (if (and (minusp x
) (oddp n
))
1710 (if (and (minusp nn
) (oddp nn
)) (- besn
) besn
))))
1713 ;;; bug 233b: lvar lambda-var equality in constraint propagation
1715 ;; Put this in a separate function.
1716 (defun test-constraint-propagation/ref
()
1718 (if (multiple-value-prog1 x
(setq x t
))
1722 (test-util:with-test
(:name
(:compiler
:constraint-propagation
:ref
))
1723 (assert (eq t
(test-constraint-propagation/ref
))))
1725 ;; Put this in a separate function.
1726 (defun test-constraint-propagation/typep
(x y
)
1727 (if (typep (multiple-value-prog1 x
(setq x y
))
1732 (test-util:with-test
(:name
(:compiler
:constraint-propagation
:typep
))
1733 (assert (= 6.0d0
(test-constraint-propagation/typep
1d0
5))))
1735 (test-util:with-test
(:name
(:compiler
:constraint-propagation
:eq
/eql
))
1736 (assert (eq :right
(let ((c :wrong
))
1737 (if (eq (let ((x c
))
1744 ;;; Put this in a separate function.
1745 (defun test-constraint-propagation/cast
(x)
1746 (when (the double-float
(multiple-value-prog1
1751 (test-util:with-test
(:name
(:compiler
:constraint-propagation
:cast
))
1752 (assertoid:assert-error
1753 (test-constraint-propagation/cast
1) type-error
))
1756 (let ((result (make-array 50000 :fill-pointer
0 :adjustable t
)))
1757 (defun string->html
(string &optional
(max-length nil
))
1758 (when (and (numberp max-length
)
1759 (> max-length
(array-dimension result
0)))
1760 (setf result
(make-array max-length
:fill-pointer
0 :adjustable t
)))
1763 (labels ((add-char (it)
1764 (setf (aref result index
) it
)
1767 (loop for ch across it do
1769 (loop for char across string do
1770 (cond ((char= char
#\
<)
1771 (add-string "<"))
1773 (add-string ">"))
1775 (add-string "&"))
1777 (add-string "'"))
1778 ((char= char
#\newline
)
1779 (add-string "<br>"))
1781 (if left-quote?
(add-string "“") (add-string "”"))
1782 (setf left-quote?
(not left-quote?
)))
1785 (setf (fill-pointer result
) index
)
1786 (coerce result
'string
)))))
1788 ;;; Calling thru constant symbols
1789 (require :sb-introspect
)
1791 (declaim (inline target-fun
))
1792 (defun target-fun (arg0 arg1
)
1794 (declaim (notinline target-fun
))
1796 ;; FIXME: should use compiler-test-util, not sb-introspect here.
1797 ;; That issue aside, neither sb-introspect nor ctu:find-named-callees
1798 ;; can examine an interpreted function for its callees,
1799 ;; so we can't actually use this function.
1800 (defun test-target-fun-called (fun res
)
1801 (assert (member #'target-fun
1802 (sb-introspect:find-function-callees
#'caller-fun-1
)))
1803 (assert (equal (funcall fun
) res
)))
1805 (defun caller-fun-1 ()
1806 (funcall 'target-fun
1 2))
1807 #-interpreter
(test-target-fun-called #'caller-fun-1
3)
1809 (defun caller-fun-2 ()
1810 (declare (inline target-fun
))
1811 (apply 'target-fun
1 '(3)))
1812 #-interpreter
(test-target-fun-called #'caller-fun-2
4)
1814 (defun caller-fun-3 ()
1815 (flet ((target-fun (a b
)
1817 (list (funcall #'target-fun
1 4) (funcall 'target-fun
1 4))))
1818 #-interpreter
(test-target-fun-called #'caller-fun-3
(list -
3 5))
1820 ;;; Reported by NIIMI Satoshi
1821 ;;; Subject: [Sbcl-devel] compilation error with optimization
1822 ;;; Date: Sun, 09 Apr 2006 17:36:05 +0900
1823 (defun test-minimal-debug-info-for-unstored-but-used-parameter (n a
)
1824 (declare (optimize (speed 3)
1828 (test-minimal-debug-info-for-unstored-but-used-parameter (1- n
) a
)))
1830 ;;; &KEY arguments with non-constant defaults.
1831 (declaim (notinline opaque-identity
))
1832 (defun opaque-identity (x) x
)
1833 (defstruct tricky-defaults
1834 (fun #'identity
:type function
)
1835 (num (opaque-identity 3) :type fixnum
))
1836 (macrolet ((frob (form expected-expected-type
)
1837 `(handler-case ,form
1838 (type-error (c) (assert (eq (type-error-expected-type c
)
1839 ',expected-expected-type
)))
1840 (:no-error
(&rest vals
) (error "~S returned values: ~S" ',form vals
)))))
1841 (frob (make-tricky-defaults :fun
3) function
)
1842 (frob (make-tricky-defaults :num
#'identity
) fixnum
))
1844 (test-util:with-test
(:name
(compile &key
:non-constant
:default
))
1845 (let ((fun (test-util:checked-compile
1846 '(lambda (&key
(key (opaque-identity 3)))
1847 (declare (optimize safety
) (type integer key
))
1849 (assert (= (funcall fun
) 3))
1850 (assert (= (funcall fun
:key
17) 17))
1851 (handler-case (funcall fun
:key t
)
1852 (type-error (c) (assert (eq (type-error-expected-type c
) 'integer
)))
1853 (:no-error
(&rest vals
) (declare (ignore vals
)) (error "no error")))))
1855 ;;; Basic compiler-macro expansion
1856 (define-compiler-macro test-cmacro-0
() ''expanded
)
1858 ;; The interpreter is not required to expand compiler-macros.
1859 ;; (Actually neither is the compiler!)
1860 #-interpreter
(assert (eq 'expanded
(funcall (lambda () (test-cmacro-0)))))
1862 ;;; FUNCALL forms in compiler macros, lambda-list parsing
1863 (define-compiler-macro test-cmacro-1
1864 (&whole whole a
(a2) &optional b
&rest c
&key d
)
1865 (list whole a a2 b c d
))
1867 (macrolet ((test (form a a2 b c d
)
1868 `(let ((form ',form
))
1869 (destructuring-bind (whole a a2 b c d
)
1870 (funcall (compiler-macro-function 'test-cmacro-1
) form nil
)
1871 (assert (equal whole form
))
1873 (assert (eql a2
,a2
))
1875 (assert (equal c
,c
))
1876 (assert (eql d
,d
))))) )
1877 (test (funcall 'test-cmacro-1
1 (x) 2 :d
3) 1 'x
2 '(:d
3) 3)
1878 (test (test-cmacro-1 11 (y) 12 :d
13) 11 'y
12 '(:d
13) 13))
1880 ;;; FUNCALL forms in compiler macros, expansions
1881 (define-compiler-macro test-cmacro-2
() ''ok
)
1883 #-interpreter
(assert (eq 'ok
(funcall (lambda () (funcall 'test-cmacro-2
)))))
1884 #-interpreter
(assert (eq 'ok
(funcall (lambda () (funcall #'test-cmacro-2
)))))
1886 ;;; Shadowing of compiler-macros by local functions
1887 (define-compiler-macro test-cmacro-3
() ''global
)
1889 (defmacro find-cmacro-3
(&environment env
)
1890 (compiler-macro-function 'test-cmacro-3 env
))
1892 (assert (funcall (lambda () (find-cmacro-3))))
1893 (assert (not (funcall (lambda () (flet ((test-cmacro-3 ()))
1894 (find-cmacro-3))))))
1895 (assert (eq 'local
(funcall (lambda () (flet ((test-cmacro-3 () 'local
))
1896 (test-cmacro-3))))))
1897 (assert (eq 'local
(funcall (lambda () (flet ((test-cmacro-3 () 'local
))
1898 (funcall #'test-cmacro-3
))))))
1900 (assert (eq 'global
(funcall (lambda () (flet ((test-cmacro-3 () 'local
))
1901 (funcall 'test-cmacro-3
))))))
1903 ;;; Local NOTINLINE & INLINE
1904 (defun test-cmacro-4 () 'fun
)
1905 (define-compiler-macro test-cmacro-4
() ''macro
)
1907 (assert (eq 'fun
(funcall (lambda ()
1908 (declare (notinline test-cmacro-4
))
1912 (assert (eq 'macro
(funcall (lambda ()
1913 (declare (inline test-cmacro-4
))
1916 ;;; SETF function compiler macros
1917 (define-compiler-macro (setf test-cmacro-4
) (&whole form value
) ''ok
)
1920 (assert (eq 'ok
(funcall (lambda () (setf (test-cmacro-4) 'zot
)))))
1922 (assert (eq 'ok
(funcall (lambda () (funcall #'(setf test-cmacro-4
) 'zot
)))))
1924 ;;; Step instrumentation breaking type-inference
1925 (test-util:with-test
(:name
(compile :insert-step-conditions
:type-inference
))
1926 (assert (= 42 (funcall (test-util:checked-compile
1928 (declare (optimize sb-c
:insert-step-conditions
))
1929 (if (typep (the function x
) 'fixnum
)
1930 (svref v
(the function x
))
1932 nil
(constantly 42)))))
1934 ;;; bug 368: array type intersections in the compiler
1938 (i368s (make-array 0 :fill-pointer t
) :type
(or (vector i368
) null
)))
1940 (g368 (error "missing :G368") :type g368
:read-only t
))
1941 (declaim (ftype (function (fixnum (vector i368
) e368
) t
) r368
))
1942 (declaim (ftype (function (fixnum (vector e368
)) t
) h368
))
1943 (defparameter *h368-was-called-p
* nil
)
1944 (defun nsu (vertices e368
)
1945 (let ((i368s (g368-i368s (make-g368))))
1946 (let ((fuis (r368 0 i368s e368
)))
1947 (format t
"~&FUIS=~S~%" fuis
)
1948 (or fuis
(h368 0 i368s
)))))
1950 (declare (ignore w x y
))
1953 (declare (ignore w x
))
1954 (setf *h368-was-called-p
* t
)
1955 (make-s368 :g368
(make-g368)))
1956 (let ((nsu (nsu #() (make-e368))))
1957 (format t
"~&NSU returned ~S~%" nsu
)
1958 (format t
"~&*H368-WAS-CALLED-P*=~S~%" *h368-was-called-p
*)
1959 (assert (s368-p nsu
))
1960 (assert *h368-was-called-p
*))
1962 ;;; bug 367: array type intersections in the compiler
1966 (i367s (make-array 0 :fill-pointer t
) :type
(or (vector i367
) null
)))
1968 (g367 (error "missing :G367") :type g367
:read-only t
))
1969 (declaim (ftype (function ((vector i367
) e367
) (or s367 null
)) r367
))
1970 (declaim (ftype (function ((vector e367
)) (values)) h367
))
1971 (defun frob-367 (v w
)
1972 (let ((x (g367-i367s (make-g367))))
1973 (let* ((y (or (r367 x w
)
1976 (format t
"~&Y=~S Z=~S~%" y z
)
1978 (defun r367 (x y
) (declare (ignore x y
)) nil
)
1979 (defun h367 (x) (declare (ignore x
)) (values))
1980 (assertoid:assert-error
(frob-367 0 (make-e367)) type-error
)
1983 (delete-file (compile-file "circ-tree-test.lisp"))
1984 (storage-condition (e)
1987 ;;; warnings due to step-instrumentation
1988 (defclass debug-test-class
() ())
1989 (test-util:checked-compile
1991 (declare (optimize (debug 3)))
1992 (defmethod print-object ((x debug-test-class
) s
)
1993 (call-next-method))))
1995 ;;; program-error from bad lambda-list keyword
1996 (test-util:with-test
(:name
(compile :bad lambda-list keyword program-error
))
1997 (multiple-value-bind (fun failure-p
)
1998 (test-util:checked-compile
'(lambda (&whole x
)
2002 (assertoid:assert-error
(funcall fun
) program-error
)))
2004 (test-util:with-test
(:name
(eval :bad lambda-list keyword program-error
)
2005 :skipped-on
(not :sb-eval
))
2006 (assertoid:assert-error
(let ((*evaluator-mode
* :interpret
))
2007 (funcall (eval '(lambda (&whole x
)
2011 ;;; ignore &environment
2012 (test-util:with-test
(:name
(defmacro ignore
&environment
))
2013 (test-util:checked-compile
2015 (defmacro macro-ignore-env
(&environment env
)
2016 (declare (ignore env
))
2019 (test-util:with-test
(:name
(defmacro :no
&environment
))
2020 (test-util:checked-compile
2022 (defmacro macro-no-env
()
2025 (test-util:with-test
(:name
(disassemble :source-form
))
2026 (dolist (*evaluator-mode
* '(#+sb-eval
:interpret
:compile
))
2027 (disassemble (eval '(defun disassemble-source-form-bug (x y z
)
2028 (declare (optimize debug
))
2030 :stream
(make-broadcast-stream))))
2032 ;;; long-standing bug in defaulting unknown values on the x86-64,
2033 ;;; since changing the calling convention (test case by Christopher
2034 ;;; Laux sbcl-help 30-06-2007)
2036 (defun default-values-bug-demo-sub ()
2039 (compile 'default-values-bug-demo-sub
)
2041 (defun default-values-bug-demo-main ()
2042 (multiple-value-bind (a b c d e f g h
)
2043 (default-values-bug-demo-sub)
2044 (if a
(+ a b c d e f g h
) t
)))
2045 (compile 'default-values-bug-demo-main
)
2047 (test-util:with-test
(:name
(multiple-value-bind :default-values
))
2048 (assert (default-values-bug-demo-main)))
2050 ;;; copy propagation bug reported by Paul Khuong
2052 (defun local-copy-prop-bug-with-move-arg (x)
2057 (multiple-value-bind (a b
)
2061 (test-util:with-test
(:name
(labels multiple-value-bind
:copy-propagation
))
2062 (assert (equal '(0 1) (multiple-value-list
2063 (local-copy-prop-bug-with-move-arg nil
))))
2064 (assert (equal '(1 0) (multiple-value-list
2065 (local-copy-prop-bug-with-move-arg t
)))))
2067 ;;;; with-pinned-objects & unwind-protect, using all non-tail conventions
2069 (defun wpo-quux () (list 1 2 3))
2070 (defvar *wpo-quux
* #'wpo-quux
)
2074 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2075 (values (funcall *wpo-quux
*)))))
2076 (assert (equal '(1 2 3) (wpo-call)))
2078 (defun wpo-multiple-call ()
2080 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2081 (funcall *wpo-quux
*))))
2082 (assert (equal '(1 2 3) (wpo-multiple-call)))
2084 (defun wpo-call-named ()
2086 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2087 (values (wpo-quux)))))
2088 (assert (equal '(1 2 3) (wpo-call-named)))
2090 (defun wpo-multiple-call-named ()
2092 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2094 (assert (equal '(1 2 3) (wpo-multiple-call-named)))
2096 (defun wpo-call-variable (&rest args
)
2098 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2099 (values (apply *wpo-quux
* args
)))))
2100 (assert (equal '(1 2 3) (wpo-call-variable)))
2102 (defun wpo-multiple-call-variable (&rest args
)
2104 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2105 (apply #'wpo-quux args
))))
2106 (assert (equal '(1 2 3) (wpo-multiple-call-named)))
2108 (defun wpo-multiple-call-local ()
2112 (sb-sys:with-pinned-objects
(*wpo-quux
*)
2114 (assert (equal '(1 2 3) (wpo-multiple-call-local)))
2116 ;;; bug 417: toplevel NIL confusing source path logic
2118 (delete-file (let ((*error-output
* (make-broadcast-stream)))
2119 (compile-file "bug-417.lisp" :verbose nil
:print nil
)))
2120 (sb-ext:code-deletion-note
(e)
2123 ;;; unknown values return convention getting disproportionate
2124 ;;; amounts of values.
2125 (declaim (notinline one-value two-values
))
2126 (defun one-value (x)
2128 (defun two-values (x y
)
2130 (defun wants-many-values (x y
)
2131 (multiple-value-bind (a b c d e f
)
2133 (assert (and (eql (not y
) a
)
2134 (not (or b c d e f
)))))
2135 (multiple-value-bind (a b c d e f
)
2137 (assert (and (eql a x
) (eql b y
)
2138 (not (or c d e f
)))))
2139 (multiple-value-bind (a b c d e f g h i
)
2141 (assert (and (eql (not y
) a
)
2142 (not (or b c d e f g h i
)))))
2143 (multiple-value-bind (a b c d e f g h i
)
2145 (assert (and (eql a x
) (eql b y
)
2146 (not (or c d e f g h i
)))))
2147 (multiple-value-bind (a b c d e f g h i j k l m n o p q r s
)
2149 (assert (and (eql (not y
) a
)
2150 (not (or b c d e f g h i j k l m n o p q r s
)))))
2151 (multiple-value-bind (a b c d e f g h i j k l m n o p q r s
)
2153 (assert (and (eql a x
) (eql b y
)
2154 (not (or c d e f g h i j k l m n o p q r s
))))))
2155 (wants-many-values 1 42)
2157 ;;; constant coalescing
2159 (defun count-code-constants (x f
)
2160 (let ((code (sb-kernel:fun-code-header f
))
2162 (loop for i from sb-vm
:code-constants-offset below
(sb-kernel:code-header-words code
)
2163 do
(when (equal x
(sb-kernel:code-header-ref code i
))
2169 (defun compile2 (lambda)
2170 (let* ((lisp "compiler-impure-tmp.lisp")
2171 (fasl (compile-file-pathname lisp
)))
2174 (with-open-file (f lisp
:direction
:output
)
2175 (prin1 `(setf *lambda
* ,lambda
) f
))
2176 (multiple-value-bind (fasl warn fail
)
2177 (compile-file lisp
:verbose nil
:print nil
)
2178 (declare (ignore warn
))
2180 (error "File-compiling ~S failed." lambda
))
2181 (let ((*lambda
* nil
))
2183 (values *lambda
* (test-util:checked-compile lambda
)))))
2184 (ignore-errors (delete-file lisp
))
2185 (ignore-errors (delete-file fasl
)))))
2187 ;; named and unnamed
2188 (defconstant +born-to-coalesce
+ '.born-to-coalesce.
)
2189 (multiple-value-bind (file-fun core-fun
)
2190 (compile2 '(lambda ()
2191 (let ((x (cons +born-to-coalesce
+ nil
))
2192 (y (cons '.born-to-coalesce. nil
)))
2194 (assert (= 1 (count-code-constants '.born-to-coalesce. file-fun
)))
2195 (assert (= 1 (count-code-constants '.born-to-coalesce. core-fun
))))
2197 ;; some things must retain identity under COMPILE, but we want to coalesce them under COMPILE-FILE
2198 (defun assert-coalescing (constant)
2199 (let ((value (copy-seq (symbol-value constant
))))
2200 (multiple-value-bind (file-fun core-fun
)
2201 (compile2 `(lambda ()
2202 (let ((x (cons ,constant nil
))
2203 (y (cons ',value nil
)))
2205 (assert (= 1 (count-code-constants value file-fun
)))
2206 (assert (= 2 (count-code-constants value core-fun
)))
2207 (let* ((l (funcall file-fun
))
2209 (b (car (second l
))))
2210 (assert (and (equal value a
)
2213 (let* ((l (funcall core-fun
))
2215 (b (car (second l
))))
2216 (assert (and (equal value a
)
2218 (not (eq a b
))))))))
2220 (defconstant +born-to-coalesce2
+ "maybe coalesce me!")
2221 (assert-coalescing '+born-to-coalesce2
+)
2223 (defconstant +born-to-coalesce3
+ #*01101001011101110100011)
2224 (assert-coalescing '+born-to-coalesce3
+)
2226 (defconstant +born-to-coalesce4
+ '(foo bar
"zot" 123 (nested "quux") #*0101110010))
2227 (assert-coalescing '+born-to-coalesce4
+)
2229 (defclass some-constant-thing
() ())
2231 ;;; correct handling of nested things loaded via SYMBOL-VALUE
2232 (defvar *sneaky-nested-thing
* (list (make-instance 'some-constant-thing
)))
2233 (defconstant +sneaky-nested-thing
+ *sneaky-nested-thing
*)
2234 (multiple-value-bind (file-fun core-fun
) (compile2 '(lambda () +sneaky-nested-thing
+))
2235 (assert (equal *sneaky-nested-thing
* (funcall file-fun
)))
2236 (assert (equal *sneaky-nested-thing
* (funcall core-fun
))))
2238 ;;; catch constant modifications thru undefined variables
2239 (defun sneak-set-dont-set-me (x)
2240 (ignore-errors (setq dont-set-me x
)))
2241 (defconstant dont-set-me
42)
2242 (assert (not (sneak-set-dont-set-me 13)))
2243 (assert (= 42 dont-set-me
))
2244 (defun sneak-set-dont-set-me2 (x)
2245 (ignore-errors (setq dont-set-me2 x
)))
2246 (defconstant dont-set-me2
(make-instance 'some-constant-thing
))
2247 (assert (not (sneak-set-dont-set-me2 13)))
2248 (assert (typep dont-set-me2
'some-constant-thing
))
2250 ;;; check that non-trivial constants are EQ across different files: this is
2251 ;;; not something ANSI either guarantees or requires, but we want to do it
2253 (defconstant +share-me-1
+ #-inline-constants
123.456d0
#+inline-constants nil
)
2254 (defconstant +share-me-2
+ "a string to share")
2255 (defconstant +share-me-3
+ (vector 1 2 3))
2256 (defconstant +share-me-4
+ (* 2 most-positive-fixnum
))
2257 (multiple-value-bind (f1 c1
) (compile2 '(lambda () (values +share-me-1
+
2261 #-inline-constants pi
)))
2262 (multiple-value-bind (f2 c2
) (compile2 '(lambda () (values +share-me-1
+
2266 #-inline-constants pi
)))
2267 (flet ((test (fa fb
)
2270 (multiple-value-list (funcall fa
))
2271 (multiple-value-list (funcall fb
)))))
2276 ;;; user-defined satisfies-types cannot be folded
2277 (deftype mystery
() '(satisfies mysteryp
))
2278 (defvar *mystery
* nil
)
2279 (defun mysteryp (x) (eq x
*mystery
*))
2280 (defstruct thing
(slot (error "missing") :type mystery
))
2281 (defun test-mystery (m) (when (eq :mystery
(thing-slot m
)) :ok
))
2282 (setf *mystery
* :mystery
)
2283 (assert (eq :ok
(test-mystery (make-thing :slot
:mystery
))))
2285 ;;; Singleton types can also be constant.
2286 (test-util:with-test
(:name
:propagate-singleton-types-to-eql
)
2287 (macrolet ((test (type value
&aux
(fun (gensym "FUN")))
2289 (declaim (ftype (function () (values ,type
&optional
)) ,fun
))
2297 (test (eql foo
) foo
)
2298 (test (integer 0 0) 0)
2299 (test (double-float 0d0
0d0
) 0d0
)
2300 (test (eql #\c
) #\c
))))
2302 (declaim (ftype (function () (integer 42 42)) bug-655581
))
2303 (defun bug-655581 ()
2305 (declaim (notinline bug-655581
))
2306 (test-util:with-test
(:name
:bug-655581
)
2307 (test-util:checked-compile-and-assert
()
2309 (ctu:compiler-derived-type
(bug-655581)))
2310 (() (values '(integer 42 42) t
))))
2312 (test-util:with-test
(:name
:clear-derived-types-on-set-fdefn
)
2313 (let ((*evaluator-mode
* :compile
)
2314 (*derive-function-types
* t
))
2316 (defun clear-derived-types-on-set-fdefn-1 ()
2318 (setf (symbol-function 'clear-derived-types-on-set-fdefn-1
)
2319 (constantly "foobar"))
2320 (defun clear-derived-types-on-set-fdefn-2 ()
2321 (length (clear-derived-types-on-set-fdefn-1)))))
2322 (assert (= 6 (clear-derived-types-on-set-fdefn-2)))))
2324 (test-util:with-test
(:name
(:bug-655126
:derive-function-types t
))
2325 (let ((*evaluator-mode
* :compile
)
2326 (*derive-function-types
* t
))
2327 (eval `(defun bug-655126 (x) x
))
2328 ;; Full warnings are ok due to *derive-function-types* = T.
2329 (assert (eq :full-warning
2331 (eval `(defun bug-655126-2 ()
2333 ((and warning
(not style-warning
)) ()
2335 (assert (eq 'bug-655126
2337 (eval `(defun bug-655126 (x y
)
2339 ((and warning
(not sb-kernel
:redefinition-warning
)) ()
2341 (assert (eq :full-warning
2343 (eval `(defun bug-655126 (x)
2347 (not sb-kernel
:redefinition-warning
)) ()
2350 (test-util:with-test
(:name
(:bug-655126
:derive-function-types nil
))
2351 (let ((*evaluator-mode
* :compile
))
2352 (eval `(defun bug-655126/b
(x) x
))
2353 ;; Just style-warning here.
2354 (assert (eq :style-warning
2356 (eval `(defun bug-655126-2/b
()
2360 (assert (eq 'bug-655126
/b
2362 (eval `(defun bug-655126/b
(x y
)
2364 ((and warning
(not sb-kernel
:redefinition-warning
)) ()
2366 ;; Bogus self-call is always worth a full one.
2367 (assert (eq :full-warning
2369 (eval `(defun bug-655126/b
(x)
2370 (bug-655126/b x y
)))
2373 (not sb-kernel
:redefinition-warning
)) ()
2376 (test-util:with-test
(:name
:bug-657499
)
2377 ;; Don't trust derived types within the compilation unit.
2379 `((declaim (optimize safety
))
2380 (defun bug-657499-foo ()
2382 (defun bug-657499-bar ()
2383 (let ((cons (bug-657499-foo)))
2387 (locally (declare (optimize safety
))
2388 (setf (symbol-function 'bug-657499-foo
) (constantly "foobar"))
2389 (assert (eq :type-error
2391 (funcall 'bug-657499-bar
)
2393 (assert (eq 'cons
(type-error-expected-type e
)))
2394 (assert (equal "foobar" (type-error-datum e
)))
2397 (declaim (unsigned-byte *symbol-value-test-var
*))
2398 (defvar *symbol-value-test-var
*)
2400 (declaim (unsigned-byte **global-symbol-value-test-var
**))
2401 (defglobal **global-symbol-value-test-var
** 0)
2403 (test-util:with-test
(:name
:symbol-value-type-derivation
)
2404 (let ((fun (compile nil
`(lambda () *symbol-value-test-var
*))))
2405 (assert (equal '(function () (values unsigned-byte
&optional
))
2406 (%simple-fun-type fun
))))
2407 (let ((fun (compile nil
`(lambda () **global-symbol-value-test-var
**))))
2408 (assert (equal '(function () (values unsigned-byte
&optional
))
2409 (%simple-fun-type fun
))))
2410 (let ((ufix (type-specifier (specifier-type `(and unsigned-byte fixnum
)))))
2411 ;; Test a free type decl
2412 (let ((fun (compile nil
`(lambda ()
2413 (declare (fixnum *symbol-value-test-var
*))
2414 (symbol-value '*symbol-value-test-var
*)))))
2415 (assert (equal `(function () (values ,ufix
&optional
))
2416 (%simple-fun-type fun
))))
2417 ;; Test a bound type decl
2418 (let ((fun (compile nil
`(lambda (*symbol-value-test-var
*)
2419 (declare (fixnum *symbol-value-test-var
*))
2420 (symbol-value '*symbol-value-test-var
*)))))
2421 (assert (equal `(function (,ufix
) (values ,ufix
&optional
))
2422 (%simple-fun-type fun
)))))
2426 (declare (fixnum **global-symbol-value-test-var
**))
2427 (symbol-global-value '**global-symbol-value-test-var
**))))
2428 (ufix (type-specifier (specifier-type `(and unsigned-byte fixnum
)))))
2429 (assert (equal `(function () (values ,ufix
&optional
))
2430 (%simple-fun-type fun
)))))
2432 (test-util:with-test
(:name
:mv-bind-to-let-type-propagation
)
2433 (let ((f (test-util:checked-compile
2435 (declare (optimize speed
)
2436 (type (integer 20 50) x
))
2437 (< (truncate x
10) 1))))
2438 (g (test-util:checked-compile
2440 (declare (optimize speed
)
2441 (type (integer 20 50) x
))
2442 (< (nth-value 1 (truncate x
10)) 10))))
2443 (h (test-util:checked-compile
2445 (declare (optimize speed
)
2446 (type (integer 20 50) x
))
2447 (multiple-value-bind (q r
)
2449 (declare (ignore r
))
2451 (type0 '(function ((integer 20 50)) (values null
&optional
)))
2452 (type1 '(function ((integer 20 50)) (values (member t
) &optional
))))
2453 (assert (equal type0
(sb-kernel:%simple-fun-type f
)))
2454 (assert (equal type1
(sb-kernel:%simple-fun-type g
)))
2455 (assert (equal type0
(sb-kernel:%simple-fun-type h
)))))
2457 (test-util:with-test
(:name
:bug-308921
)
2458 (let ((*check-consistency
* t
))
2460 `((let ((exported-symbols-alist
2461 (loop for symbol being the external-symbols of
:cl
2462 collect
(cons symbol
2463 (concatenate 'string
2465 (string-downcase symbol
))))))
2466 (defun hyperdoc-lookup (symbol)
2467 (cdr (assoc symbol exported-symbols-alist
)))))
2470 (test-util:with-test
(:name
:bug-308941
)
2471 (multiple-value-bind (warn fail
)
2472 (let ((*check-consistency
* t
))
2474 "(eval-when (:compile-toplevel :load-toplevel :execute)
2477 (foo #.(make-foo3)))"
2479 ;; ...but the compiler should not break.
2480 (assert (and warn fail
))))
2482 (test-util:with-test
(:name
:bug-903821
)
2483 (let* ((fun (test-util:checked-compile
2485 (declare (sb-ext:word x
)
2486 (type (integer 0 #.
(1- sb-vm
:n-machine-word-bits
)) n
)
2488 (logandc2 x
(ash -
1 n
)))))
2490 (intern (format nil
"ASH-LEFT-MOD~D" sb-vm
::n-machine-word-bits
) "SB-VM")))
2491 (assert (not (member (symbol-function thing-not-to-call
)
2492 (ctu:find-named-callees fun
))))
2493 (assert (= 7 (funcall fun
15 3)))))
2495 (test-util:with-test
(:name
:bug-997528
)
2496 (let ((fun (test-util:checked-compile
2498 (declare (optimize (speed 0) (space 0))
2499 (type (integer -
228645653448155482 -
228645653447928749) x
))
2500 (floor 1.0 (the (integer -
228645653448151677 -
228645653448150900) x
))))))
2501 (multiple-value-bind (quo rem
)
2502 (funcall fun -
228645653448151381)
2504 (assert (= rem
(float -
228645653448151381))))))
2506 (defmacro def-many-code-constants
()
2507 `(defun many-code-constants ()
2508 ,@(loop for i from
0 below
1000
2509 collect
`(print ,(format nil
"hi-~d" i
)))))
2511 (test-util:with-test
(:name
:many-code-constants
)
2512 (def-many-code-constants)
2513 (assert (search "hi-999"
2514 (with-output-to-string (*standard-output
*)
2515 (many-code-constants)))))
2517 (test-util:with-test
(:name
:bug-943953
)
2518 ;; we sometimes splice compiler structures like clambda in
2519 ;; source, and our error reporting would happily use that
2521 (let* ((src "bug-943953.lisp")
2522 (obj (compile-file-pathname src
)))
2523 (unwind-protect (let ((*error-output
* (make-broadcast-stream)))
2524 (compile-file src
:verbose nil
:print nil
))
2525 (ignore-errors (delete-file obj
)))))
2527 (declaim (inline vec-1177703
))
2528 (defstruct (vec-1177703 (:constructor vec-1177703
(&optional x
)))
2529 (x 0.0d0
:type double-float
))
2531 (declaim (inline norm-1177703
))
2532 (defun norm-1177703 (v)
2533 (vec-1177703 (sqrt (vec-1177703-x v
))))
2535 (test-util:with-test
(:name
:bug-1177703
)
2536 (test-util:checked-compile
`(lambda (x)
2537 (norm-1177703 (vec-1177703 x
)))))
2539 (declaim (inline call-1035721
))
2540 (defun call-1035721 (function)
2542 (funcall function x
)))
2544 (declaim (inline identity-1035721
))
2545 (defun identity-1035721 (x)
2548 (test-util:with-test
(:name
:bug-1035721
)
2549 (test-util:checked-compile
2552 (call-1035721 #'identity-1035721
)
2554 (identity-1035721 x
))))))
2556 (test-util:with-test
(:name
:expt-type-derivation-and-method-redefinition
)
2557 (defmethod expt-type-derivation ((x list
) &optional
(y 0.0))
2558 (declare (type float y
))
2560 ;; the redefinition triggers a type lookup of the old
2561 ;; fast-method-function's type, which had a bogus type specifier of
2562 ;; the form (double-float 0) from EXPT type derivation
2563 (defmethod expt-type-derivation ((x list
) &optional
(y 0.0))
2564 (declare (type float y
))
2567 ;; Lp# 1066451 - declarations were either misplaced or dropped
2568 ;; depending on whether the :policy argument was used in DEFTRANSFORM.
2569 ;; That was a bit random. :policy doesn't affect whether decls
2570 ;; are accepted now.
2572 (declare (special randomness-factor
))
2573 (if (constant-lvar-p randomness-factor
)
2574 (format nil
"Weird transform answer is ~D"
2575 (+ (lvar-value randomness-factor
) blah
))))
2576 (defknown weird-fn
(integer symbol
&key
(:magic real
)) t
)
2577 (deftransform weird-fn
((x s
&key
((:magic randomness-factor
)))
2578 (fixnum t
&key
(:magic fixnum
)))
2579 ;; I can't see much use for declarations other than SPECIAL here,
2580 ;; but we shouldn't supposedly allow them and then not handle them right.
2581 (declare (special fred
) (special randomness-factor
) (lvar x s
))
2583 (test-util:with-test
(:name
:deftransform-bug-1066451
)
2584 (let ((f (let ((fred 3))
2585 (declare (special fred
))
2586 (test-util:checked-compile
2587 '(lambda () (weird-fn 2 'foo
:magic
11))))))
2588 (assert (string= (funcall f
)
2589 "Weird transform answer is 14"))))
2591 (defun skip-1-passthrough (a b sb-int
:&more context count
)
2592 (declare (ignore a b
))
2593 (multiple-value-call 'list
2595 (sb-c::%more-arg-values context
1 (1- (truly-the fixnum count
)))
2597 (defun skip-2-passthrough (a b sb-int
:&more context count
)
2598 (declare (ignore a b
))
2599 (multiple-value-call 'list
2601 (sb-c::%more-arg-values context
2 (- (truly-the fixnum count
) 2))
2603 (defun skip-n-passthrough (n-skip n-copy sb-int
:&more context count
)
2604 (assert (>= count
(+ n-copy n-skip
))) ; prevent crashes
2605 (multiple-value-call 'list
2607 (sb-c::%more-arg-values context n-skip n-copy
)
2610 ;; %MORE-ARG-VALUES was wrong on x86 and x86-64 with nonzero 'skip'.
2611 ;; It's entirely possible that other backends are also not working.
2612 (test-util:with-test
(:name
:more-arg-fancy
2613 :skipped-on
:interpreter
)
2614 (assert (equal (skip-1-passthrough 0 0 'a
'b
'c
'd
'e
'f
)
2615 '(start b c d e f end
)))
2616 (assert (equal (skip-2-passthrough 0 0 'a
'b
'c
'd
'e
'f
)
2617 '(start c d e f end
)))
2618 (assert (equal (skip-n-passthrough 1 5 'a
'b
'c
'd
'e
'f
)
2619 '(start b c d e f end
)))
2620 (assert (equal (skip-n-passthrough 1 5 'a
'b
'c
'd
'e
'f
'g
)
2621 '(start b c d e f end
)))
2622 (assert (equal (skip-n-passthrough 2 5 'a
'b
'c
'd
'e
'f
'g
)
2623 '(start c d e f g end
)))
2624 (assert (equal (skip-n-passthrough 2 5 'a
'b
'c
'd
'e
'f
'g
'h
)
2625 '(start c d e f g end
))))
2627 (test-util:with-test
(:name
:macro-policy
)
2628 (flet ((count-notes ()
2630 (handler-bind ((compiler-note
2635 (multiple-value-bind (fasl warnings errors
)
2636 (compile-file "macro-policy-test.lisp"
2637 :print nil
:verbose nil
)
2638 (ignore-errors (delete-file fasl
))
2639 (assert (and (not warnings
) (not errors
)))
2641 (let* ((baseline (count-notes))
2642 (test (progv '(*frob-macro-policy
*) '(t) (count-notes)))
2643 (baseline-again (count-notes)))
2644 (assert (/= 0 baseline
))
2646 ;; macro-policy is rebound inside compile-file
2647 (assert (= baseline-again baseline
)))))
2649 (in-package :cl-user
)
2651 (with-test (:name
:merge-lambdas-dead-return
)
2652 (let ((fasl (let ((*error-output
* (make-broadcast-stream)))
2653 (compile-file "merge-lambdas.lisp"
2654 :print nil
:verbose nil
))))
2655 (ignore-errors (delete-file fasl
))))
2657 (declaim (inline ensure-a-fun
))
2658 (defun ensure-a-fun (f) (coerce f
'function
))
2659 (defmacro compose2
(f g
)
2660 `(let ((f (ensure-a-fun ,f
))
2661 (g (ensure-a-fun ,g
)))
2662 (lambda (arg) (funcall f
(funcall g arg
)))))
2664 (with-test (:name
:coerce-to-function-smarter
)
2665 (let ((f (checked-compile
2667 (funcall (compose2 #'integerp
#'car
) x
)))))
2668 ;; should be completely inlined
2669 (assert (null (ctu:find-named-callees f
)))))
2671 (with-test (:name
:derived-function-type-casts
)
2672 (let ((fasl (compile-file "derived-function-type-casts.lisp"
2673 :print nil
:verbose nil
)))
2675 (ignore-errors (delete-file fasl
))
2676 (assert (null (funcall 'derived-function-type-casts
)))))
2678 (with-test (:name
(compile function
:invalid-function-name
))
2679 (flet ((test-case (nameoid)
2681 1 (checked-compile `(lambda () (function ,nameoid
))
2682 :allow-failure t
)))))
2685 (test-case '(foo bar
))))
2687 (defun catch-compiled-program-error (form &rest args
)
2688 (multiple-value-bind (function failure-p
)
2689 (checked-compile form
:allow-failure t
:allow-warnings t
)
2691 (assert-error (apply function args
))))
2693 (with-test (:name
:duplicate-
&key-no-error
)
2694 (catch-compiled-program-error
2695 '(lambda () (defun duplicate-&key-no-error
(&key a a
) a
))))
2697 (with-test (:name
:bad-type-specifiers
)
2698 (catch-compiled-program-error
2699 '(lambda (x) (typep x
'(values 10)))
2701 (assert (nth-value 1
2703 '(lambda () (declare (sb-ext:muffle-conditions
10)))
2704 :allow-warnings t
))))
2706 (with-test (:name
:coverage-and-errors
)
2708 '((locally (declare (optimize sb-c
:store-coverage-data
))
2711 (symbol-macrolet ((x 30))
2712 (macrolet ((foo (y) (+ x y
)))
2713 (declaim (inline environment-around-inline
))
2714 (defun environment-around-inline (z)
2717 (with-test (:name
:environment-around-inline
)
2718 (defun environment-around-inline.2 (z)
2719 (environment-around-inline z
))
2720 (assert (= (environment-around-inline.2 10) 340)))
2722 (with-test (:name
:defun-setf-return-value
)
2723 (let ((name `(setf ,(gensym))))
2724 (assert (equal (eval `(defun ,name
()))
2727 (with-test (:name
(make-sequence :unknown type
))
2728 (let ((fun (checked-compile
2730 (let ((vector (make-sequence '(simple-array make-sequence-unknown
(*)) 10)))
2731 (setf (aref vector
0) x
)
2733 :allow-style-warnings t
)))
2734 (deftype make-sequence-unknown
() 'fixnum
)
2735 (assert-error (funcall fun
'abc
) type-error
)))
2737 (with-test (:name
(:compiler-messages function
:type-specifier
))
2738 ;; Previously, function types were often printed confusingly, e.g.:
2740 ;; (function ()) => #'NIL
2741 ;; (function *) => #'*
2742 ;; (function (function a)) => #'#'A
2744 (flet ((test-case (spec)
2745 (destructuring-bind (type expected
) spec
2748 (proclaim '(ftype (function () boolean
) my-function
))
2749 (handler-bind ((warning
2751 (setf report
(princ-to-string condition
))
2753 (proclaim `(ftype ,type my-function
)))
2754 (assert (search expected report
)))
2755 (fmakunbound 'my-function
)))))
2758 `(((function ()) "(FUNCTION NIL)")
2759 ((function *) "(FUNCTION *)")
2760 ((function (function *)) "(FUNCTION (FUNCTION *))")
2761 ((function (function (eql 1))) "(FUNCTION (FUNCTION (EQL 1))")))))
2763 (with-test (:name
:boxed-ref-setf-special
2764 :skipped-on
:interpreter
)
2765 (let* ((var (gensym))
2766 (fun (checked-compile `(lambda ()
2767 (declare (special ,var
))
2768 (setf ,var
10d0
)))))
2769 (ctu:assert-no-consing
(funcall fun
))))
2771 (with-test (:name
:boxed-ref-bind-special
2772 :skipped-on
:interpreter
)
2773 (let* ((var (gensym))
2774 (fun (checked-compile `(lambda ()
2776 (declare (special ,var
)))))))
2777 (ctu:assert-no-consing
(funcall fun
))))
2779 (with-test (:name
:boxed-ref-svref
2780 :skipped-on
:interpreter
)
2781 (let ((fun (checked-compile `(lambda (x)
2782 (setf (svref x
0) 10d0
))))
2783 (vector (vector nil
)))
2784 (ctu:assert-no-consing
(funcall fun vector
))))
2786 (with-test (:name
:boxed-ref-instance-set
2787 :skipped-on
:interpreter
)
2788 (let* ((name (gensym "STRUCT"))
2790 (eval `(defstruct ,name x
))
2791 (checked-compile `(lambda (x)
2792 (setf (,(sb-int:symbolicate name
'-x
) x
)
2794 (instance (funcall (sb-int:symbolicate
'make- name
))))
2795 (ctu:assert-no-consing
(funcall fun instance
))))
2797 (with-test (:name
:boxed-ref-car
2798 :skipped-on
:interpreter
)
2799 (let ((fun (checked-compile `(lambda (x)
2801 (setf (cdr x
) 10d0
))))
2803 (ctu:assert-no-consing
(funcall fun list
))))
2806 (with-test (:name
:ftype-return-type-conflict
2807 ;; Not having UNWIND-TO-FRAME-AND-CALL-VOP changes
2808 ;; the condition type here?
2809 :fails-on
(not :unwind-to-frame-and-call-vop
))
2810 (proclaim '(ftype (function () fixnum
) ftype-return-type-conflict
))
2811 (checked-compile-and-assert (:optimize
:safe
:allow-warnings t
)
2812 `(sb-int:named-lambda ftype-return-type-conflict
() nil
)
2813 (() (condition 'type-error
))))
2816 (declaim (inline bug-1728074-to-boolean bug-1728074-foo
))
2817 (defun bug-1728074-to-boolean (x) (/= x
0))
2818 (defun bug-1728074-foo (storage key converter
)
2819 (labels ((value (entry)
2820 (funcall converter
(ash entry -
17)))
2821 (insert (start key new
)
2823 (return-from insert
(value (aref storage start
))))
2824 (let ((entry (aref storage start
)))
2825 (let* ((okey (logand entry
#xf00
))
2826 (ostart (logand okey
#xf
)))
2827 (unless (= ostart start
)
2828 (insert ostart okey entry
)))))
2830 (let ((entry (aref storage index
)))
2831 (when (= key
(logand #xf00 entry
))
2833 (declare (inline value
))
2834 (probe (logand key
#xf
))))
2836 (with-test (:name
:defined-fun-in-a-deleted-home-lambda
)
2837 (checked-compile `(lambda (cache key
) (bug-1728074-foo cache key
#'bug-1728074-to-boolean
))))
2839 (defstruct (lambda-var-ref-lvar-null (:type list
))
2843 (with-test (:name
:lambda-var-ref-lvar-null
)
2844 (assert (nth-value 1
2847 (setf (lambda-var-ref-lvar-null-x :b
) nil
2848 (lambda-var-ref-lvar-null-y a
) 0))
2849 :allow-warnings t
))))
2851 (sb-c:defknown blah
* * (sb-c:foldable
))
2852 (defun blah (x) (- x
))
2853 (with-test (:name
:foldable-wild-args-fun
)
2854 (assert (eql (funcall (checked-compile '(lambda () (blah (+ 1 2))))) -
3)))