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
18 tmpfilename="$TEST_FILESTEM.lisp"
20 # This should fail, as type inference should show that the call to FOO
21 # will return something of the wrong type.
22 cat > $tmpfilename <<EOF
24 (defun foo (x) (list x))
25 (defun bar (x) (1+ (foo x)))
27 expect_failed_compile $tmpfilename
29 # This should fail, as type inference should show that the call to FOO
30 # has a wrong number of args.
31 cat > $tmpfilename <<EOF
33 (defun foo (x) (or x (foo x x)))
35 expect_failed_compile $tmpfilename
37 # This should fail, as we define a function multiply in the same file
39 cat > $tmpfilename <<EOF
41 (defun foo (x) (list x))
42 (defun foo (x) (cons x x))
44 expect_failed_compile $tmpfilename
46 # This shouldn't fail, as the inner FLETs should not be treated as
47 # having the same name.
48 cat > $tmpfilename <<EOF
51 (flet ((baz (y) (load y)))
52 (declare (notinline baz))
55 (flet ((baz (y) (load y)))
56 (declare (notinline baz))
59 expect_clean_compile $tmpfilename
61 # This shouldn't fail because it's not really a multiple definition
62 cat > $tmpfilename <<EOF
64 (eval-when (:compile-toplevel :load-toplevel :execute)
67 expect_clean_compile $tmpfilename
70 cat > $tmpfilename <<EOF
72 (eval-when (:compile-toplevel)
76 expect_clean_compile $tmpfilename
78 # This shouldn't fail despite the apparent type mismatch, because of
79 # the NOTINLINE declamation.
80 cat > $tmpfilename <<EOF
82 (defun foo (x) (list x))
83 (declaim (notinline foo))
84 (defun bar (x) (1+ (foo x)))
86 expect_clean_compile $tmpfilename
88 # This shouldn't fail, but did until sbcl-0.8.10.4x
89 cat > $tmpfilename <<EOF
91 (declaim (inline foo))
95 (list (foo y) (if (> y 1) (funcall (if (> y 0) #'foo #'identity) y))))
97 expect_clean_compile $tmpfilename
99 # This shouldn't fail despite the apparent type mismatch, because of
100 # the NOTINLINE declaration.
101 cat > $tmpfilename <<EOF
102 (in-package :cl-user)
103 (defun foo (x) (list x))
105 (declare (notinline foo))
108 expect_clean_compile $tmpfilename
110 # This in an ideal world would fail (that is, return with FAILURE-P
111 # set), but at present it doesn't.
112 cat > $tmpfilename <<EOF
113 (in-package :cl-user)
114 (defun foo (x) (list x))
116 (declare (notinline foo))
118 (declare (inline foo))
121 # expect_failed_compile $tmpfilename
123 # This used to not warn, because the VALUES derive-type optimizer was
124 # insufficiently precise.
125 cat > $tmpfilename <<EOF
126 (in-package :cl-user)
127 (defun foo (x) (declare (ignore x)) (values))
128 (defun bar (x) (1+ (foo x)))
130 expect_failed_compile $tmpfilename
132 # Even after making the VALUES derive-type optimizer more precise, the
133 # following should still be clean.
134 cat > $tmpfilename <<EOF
135 (in-package :cl-user)
136 (defun foo (x) (declare (ignore x)) (values))
137 (defun bar (x) (car x))
139 expect_clean_compile $tmpfilename
141 # NOTINLINE on known functions shouldn't inhibit type inference
142 # (spotted by APD sbcl-devel 2003-06-14)
143 cat > $tmpfilename <<EOF
144 (in-package :cl-user)
146 (declare (notinline list))
149 expect_failed_compile $tmpfilename
151 # ERROR wants to check its format string for sanity...
152 cat > $tmpfilename <<EOF
153 (in-package :cl-user)
158 expect_failed_compile $tmpfilename
160 # ... but it (ERROR) shouldn't complain about being unable to optimize
161 # when it's uncertain about its argument's type
162 cat > $tmpfilename <<EOF
163 (in-package :cl-user)
167 fail_on_condition_during_compile sb-ext:compiler-note $tmpfilename
169 # test case from Rudi for some CLOS WARNINGness that shouldn't have
171 cat > $tmpfilename <<EOF
172 #+sb-eval (eval-when (:compile-toplevel)
173 (setf sb-ext:*evaluator-mode* :compile))
175 (eval-when (:compile-toplevel :load-toplevel :execute)
176 (defstruct buffer-state
179 (defclass buffered-stream-mixin ()
180 ((buffer-state :initform (make-buffer-state))))
182 (defgeneric frob (stream))
183 (defmethod frob ((stream t))
185 (defmethod frob ((stream buffered-stream-mixin))
187 ((index (buffer-state-output-index (slot-value stream 'buffer-state))))
191 expect_clean_compile $tmpfilename
193 # undeclared unbound variables should cause a full warning, as they
194 # invoke undefined behaviour
195 cat > $tmpfilename <<EOF
198 expect_failed_compile $tmpfilename
200 cat > $tmpfilename <<EOF
201 (declaim (special *x*))
204 expect_clean_compile $tmpfilename
206 cat > $tmpfilename <<EOF
207 (defun foo () (declare (special x)) x)
209 expect_clean_compile $tmpfilename
211 # MUFFLE-CONDITIONS tests
212 cat > $tmpfilename <<EOF
214 (declare (muffle-conditions style-warning))
217 expect_clean_compile $tmpfilename
219 cat > $tmpfilename <<EOF
221 (declare (muffle-conditions code-deletion-note))
224 fail_on_condition_during_compile sb-ext:compiler-note $tmpfilename
226 cat > $tmpfilename <<EOF
228 (declare (muffle-conditions compiler-note))
229 (declare (optimize speed))
232 fail_on_condition_during_compile sb-ext:compiler-note $tmpfilename
234 cat > $tmpfilename <<EOF
235 (declaim (muffle-conditions compiler-note))
237 (declare (optimize speed))
240 fail_on_condition_during_compile sb-ext:compiler-note $tmpfilename
242 cat > $tmpfilename <<EOF
243 (declaim (muffle-conditions compiler-note))
245 (declare (unmuffle-conditions compiler-note))
246 (declare (optimize speed))
249 expect_condition_during_compile sb-ext:compiler-note $tmpfilename
251 # undefined variable causes a WARNING
252 cat > $tmpfilename <<EOF
253 (declaim (muffle-conditions warning))
254 (declaim (unmuffle-conditions style-warning))
257 expect_clean_compile $tmpfilename
259 # top level LOCALLY behaves nicely
260 cat > $tmpfilename <<EOF
262 (declare (muffle-conditions warning))
265 expect_clean_compile $tmpfilename
267 cat > $tmpfilename <<EOF
269 (declare (muffle-conditions warning))
273 expect_failed_compile $tmpfilename
275 # This should fail, and fail nicely -- not eg. loop trying to dump
276 # references to the unbound variable.
277 cat > $tmpfilename <<EOF
278 (defmacro macro-with-unbound-variables (foo)
281 (macro-with-unbound-variables 'xxx)
283 expect_failed_compile $tmpfilename
285 # This should fail, as the MAKE-LOAD-FORM must be used for
286 # externalizing conditions, and the method for CONDITION must signal
288 cat > $tmpfilename <<EOF
289 (defvar *oops* #.(make-condition 'condition))
291 expect_failed_compile $tmpfilename
293 # This should fail, as the MAKE-LOAD-FORM must be used for objects,
294 # and the method for STANDARD.OBJECT is required to signal an error.
295 cat > $tmpfilename <<EOF
296 (defvar *oops* #.(make-instance 'standard-object))
298 expect_failed_compile $tmpfilename
300 # This should be clean
301 cat > $tmpfilename <<EOF
302 (defvar *string* (make-string 10 :element-type 'base-char))
304 expect_clean_compile $tmpfilename
306 # This should style-warn (but not warn or otherwise fail) as the call
307 # to FORMAT has too many arguments, which is bad style but not
309 cat > $tmpfilename <<EOF
311 (format nil "abc~~def" a b))
313 expect_warned_compile $tmpfilename
315 # Tests that destructive-functions on known-constant data cause
316 # compile-time warnings.
317 cat > $tmpfilename <<EOF
318 (let ((string "foo"))
320 (setf string "bar")))
322 expect_clean_compile $tmpfilename
324 cat > $tmpfilename <<EOF
329 expect_clean_compile $tmpfilename
331 cat > $tmpfilename <<EOF
336 expect_clean_compile $tmpfilename
338 cat > $tmpfilename <<EOF
339 (let ((string "foo"))
341 (replace string "bar")))
343 expect_failed_compile $tmpfilename
345 cat > $tmpfilename <<EOF
347 (setf (char "bar" 0) #\1))
349 expect_failed_compile $tmpfilename
351 cat > $tmpfilename <<EOF
352 (let ((foo '(1 2 3)))
356 expect_failed_compile $tmpfilename
358 cat > $tmpfilename <<EOF
363 expect_failed_compile $tmpfilename
365 cat > $tmpfilename <<EOF
366 (declaim (optimize (speed 3) (space 0) (safety 0)))
371 expect_clean_compile $tmpfilename
373 cat > $tmpfilename <<EOF
377 expect_clean_compile $tmpfilename
379 cat > $tmpfilename <<EOF
380 (eval-when (:compile-toplevel :load-toplevel :execute)
382 (defmethod make-load-form ((foo foox) &optional env)
383 (declare (ignore env))
388 expect_clean_compile $tmpfilename
390 cat > $tmpfilename <<EOF
391 (defun something (x) x)
393 (defun something-more (x) x)
395 expect_aborted_compile $tmpfilename
397 cat > $tmpfilename <<EOF
400 expect_clean_cload $tmpfilename
402 cat > $tmpfilename <<EOF
403 (defconstant cl-package (find-package :cl))
404 (defun cl-symbol-p (x)
405 (eq (symbol-package x) cl-package))
407 expect_clean_cload $tmpfilename
409 cat > $tmpfilename <<EOF
410 (and (eval-when (:compile-toplevel) (error "oops AND")))
411 (or (eval-when (:compile-toplevel) (error "oops OR")))
412 (cond (t (eval-when (:compile-toplevel) (error "oops COND"))))
414 expect_clean_cload $tmpfilename
416 # Test correct fasl-dumping of literals in arglist defaulting.
418 cat > $tmpfilename <<EOF
419 (in-package :cl-user)
421 ;; These are CLHS examples from the dictionary entry for MAKE-LOAD-FORM.
422 (eval-when (:compile-toplevel :load-toplevel :execute)
423 (defstruct my-struct a b c)
424 (defmethod make-load-form ((s my-struct) &optional environment)
425 (make-load-form-saving-slots s :environment environment))
426 (defclass my-class ()
427 ((x :initarg :x :reader obj-x)
428 (y :initarg :y :reader obj-y)
429 (dist :accessor obj-dist)))
430 (defmethod make-load-form ((self my-class) &optional environment)
431 (make-load-form-saving-slots self
433 :environment environment)))
435 (defun bar1 (&optional (x #.(make-my-struct)))
438 (defun bar2 (&optional (x #.(make-instance 'my-class)))
441 ;; Packages are externalizable.
442 (defun bar3 (&optional (x #.*package*))
445 (assert (typep (bar1) 'my-struct))
446 (assert (typep (bar2) 'my-class))
447 (assert (eq (bar3) *package*))
450 expect_clean_cload $tmpfilename
452 cat > $tmpfilename <<EOF
453 (in-package :cl-user)
454 (defmacro foo () (error "ERROR at macroexpansion time."))
457 expect_condition_during_compile sb-c:compiler-error $tmpfilename
459 cat > $tmpfilename <<EOF
460 (eval-when (:compile-toplevel)
461 (error "ERROR within EVAL-WHEN."))
463 expect_condition_during_compile simple-error $tmpfilename
465 cat > $tmpfilename <<EOF
466 (defun slot-name-incf (s)
467 (with-slots (no-such-slot) s
468 (incf no-such-slot)))
470 expect_clean_cload $tmpfilename
472 cat > $tmpfilename <<EOF
473 (in-package :cl-user)
476 (declare (muffle-conditions warning))
478 (declare (type double-float em))
480 (setf em (float (1+ i))))))
482 expect_clean_compile $tmpfilename
484 cat > $tmpfilename <<EOF
485 (in-package :cl-user)
488 (declare (muffle-conditions warning))
490 (declare (values fixnum))
494 expect_clean_compile $tmpfilename
496 cat > $tmpfilename <<EOF
497 (in-package :cl-user)
500 (declare (muffle-conditions warning)
501 (type (vector (mod 7) 1) x))
505 expect_clean_compile $tmpfilename
507 cat > $tmpfilename <<EOF
508 (in-package :cl-user)
510 (declaim (notinline foo))
511 (let ((i 0)) (defun foo (x) (incf i x)))
512 (defun bar (x) (foo x))
514 fail_on_condition_during_compile sb-ext:compiler-note $tmpfilename