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 # It's unclear why the majority of these tests are written in shell script when
19 # many look as though they would be perfectly happy as lisp tests.
20 # This test, on the other hand, would have a tough time as a lisp test,
21 # because it needs to make a symlink which would either mean calling run-program
22 # or using alien-funcall on symlink(). Shell is easier.
23 mkdir
-p inscrutable
/f00
24 echo '(defun zook (x) (declare (integer x)) (length x))' > inscrutable
/f00
/f00_xyz_bad
25 ln -s inscrutable
/f00
/f00_xyz_bad good.lisp
26 run_sbcl
--eval '(setq *default-pathname-defaults* #P"")' \
27 --eval '(compile-file "good.lisp" :verbose t)' --quit >stdout.out
2>stderr.out
28 egrep -q 'compiling file ".*good' stdout.out
30 egrep -q 'file:.+good' stderr.out
32 if [ $stdout_ok = 0 -a $stderr_ok = 0 ] ; then
33 rm -r good.
* stdout.out stderr.out inscrutable
34 echo "untruenames: PASS"
36 cat stdout.out stderr.out
37 echo "untruenames: FAIL"
41 ## FIXME: all these tests need to be more silent. Too much noise to parse
43 tmpfilename
="$TEST_FILESTEM.lisp"
45 # This should fail, as type inference should show that the call to FOO
46 # will return something of the wrong type.
47 cat > $tmpfilename <<EOF
49 (defun foo (x) (list x))
50 (defun bar (x) (1+ (foo x)))
52 expect_failed_compile
$tmpfilename
54 # This should fail, as type inference should show that the call to FOO
55 # has a wrong number of args.
56 cat > $tmpfilename <<EOF
58 (defun foo (x) (or x (foo x x)))
60 expect_failed_compile
$tmpfilename
62 # This should fail, as we define a function multiply in the same file
64 cat > $tmpfilename <<EOF
66 (defun foo (x) (list x))
67 (defun foo (x) (cons x x))
69 expect_failed_compile
$tmpfilename
71 # This shouldn't fail, as the inner FLETs should not be treated as
72 # having the same name.
73 cat > $tmpfilename <<EOF
76 (flet ((baz (y) (load y)))
77 (declare (notinline baz))
80 (flet ((baz (y) (load y)))
81 (declare (notinline baz))
84 expect_clean_compile
$tmpfilename
86 # This shouldn't fail because it's not really a multiple definition
87 cat > $tmpfilename <<EOF
89 (eval-when (:compile-toplevel :load-toplevel :execute)
92 expect_clean_compile
$tmpfilename
95 cat > $tmpfilename <<EOF
97 (eval-when (:compile-toplevel)
101 expect_clean_compile
$tmpfilename
103 # This shouldn't fail despite the apparent type mismatch, because of
104 # the NOTINLINE declamation.
105 cat > $tmpfilename <<EOF
106 (in-package :cl-user)
107 (defun foo (x) (list x))
108 (declaim (notinline foo))
109 (defun bar (x) (1+ (foo x)))
111 expect_clean_compile
$tmpfilename
113 # This shouldn't fail, but did until sbcl-0.8.10.4x
114 cat > $tmpfilename <<EOF
115 (in-package :cl-user)
116 (declaim (inline foo))
120 (list (foo y) (if (> y 1) (funcall (if (> y 0) #'foo #'identity) y))))
122 expect_clean_compile
$tmpfilename
124 # This shouldn't fail despite the apparent type mismatch, because of
125 # the NOTINLINE declaration.
126 cat > $tmpfilename <<EOF
127 (in-package :cl-user)
128 (defun foo (x) (list x))
130 (declare (notinline foo))
133 expect_clean_compile
$tmpfilename
135 # This in an ideal world would fail (that is, return with FAILURE-P
136 # set), but at present it doesn't.
137 cat > $tmpfilename <<EOF
138 (in-package :cl-user)
139 (defun foo (x) (list x))
141 (declare (notinline foo))
143 (declare (inline foo))
146 # expect_failed_compile $tmpfilename
148 # This used to not warn, because the VALUES derive-type optimizer was
149 # insufficiently precise.
150 cat > $tmpfilename <<EOF
151 (in-package :cl-user)
152 (defun foo (x) (declare (ignore x)) (values))
153 (defun bar (x) (1+ (foo x)))
155 expect_failed_compile
$tmpfilename
157 # Even after making the VALUES derive-type optimizer more precise, the
158 # following should still be clean.
159 cat > $tmpfilename <<EOF
160 (in-package :cl-user)
161 (defun foo (x) (declare (ignore x)) (values))
162 (defun bar (x) (car x))
164 expect_clean_compile
$tmpfilename
166 # NOTINLINE on known functions shouldn't inhibit type inference
167 # (spotted by APD sbcl-devel 2003-06-14)
168 cat > $tmpfilename <<EOF
169 (in-package :cl-user)
171 (declare (notinline list))
174 expect_failed_compile
$tmpfilename
176 # ERROR wants to check its format string for sanity...
177 cat > $tmpfilename <<EOF
178 (in-package :cl-user)
183 expect_failed_compile
$tmpfilename
185 # ... but it (ERROR) shouldn't complain about being unable to optimize
186 # when it's uncertain about its argument's type
187 cat > $tmpfilename <<EOF
188 (in-package :cl-user)
192 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
194 # test case from Rudi for some CLOS WARNINGness that shouldn't have
196 cat > $tmpfilename <<EOF
197 (eval-when (:compile-toplevel)
198 (setf sb-ext:*evaluator-mode* :compile))
200 (eval-when (:compile-toplevel :load-toplevel :execute)
201 (defstruct buffer-state
204 (defclass buffered-stream-mixin ()
205 ((buffer-state :initform (make-buffer-state))))
207 (defgeneric frob (stream))
208 (defmethod frob ((stream t))
210 (defmethod frob ((stream buffered-stream-mixin))
212 ((index (buffer-state-output-index (slot-value stream 'buffer-state))))
216 expect_clean_compile
$tmpfilename
218 # undeclared unbound variables should cause a full warning, as they
219 # invoke undefined behaviour
220 cat > $tmpfilename <<EOF
223 expect_failed_compile
$tmpfilename
225 cat > $tmpfilename <<EOF
226 (declaim (special *x*))
229 expect_clean_compile
$tmpfilename
231 cat > $tmpfilename <<EOF
232 (defun foo () (declare (special x)) x)
234 expect_clean_compile
$tmpfilename
236 # MUFFLE-CONDITIONS tests
237 cat > $tmpfilename <<EOF
239 (declare (muffle-conditions style-warning))
242 expect_clean_compile
$tmpfilename
244 cat > $tmpfilename <<EOF
246 (declare (muffle-conditions code-deletion-note))
249 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
251 cat > $tmpfilename <<EOF
253 (declare (muffle-conditions compiler-note))
254 (declare (optimize speed))
257 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
259 cat > $tmpfilename <<EOF
260 (declaim (muffle-conditions compiler-note))
262 (declare (optimize speed))
265 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
267 cat > $tmpfilename <<EOF
268 (declaim (optimize debug)
269 (muffle-conditions compiler-note))
271 (declare (optimize speed))
274 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
276 cat > $tmpfilename <<EOF
277 (declaim (muffle-conditions compiler-note))
279 (declare (unmuffle-conditions compiler-note))
280 (declare (optimize speed))
283 expect_condition_during_compile sb-ext
:compiler-note
$tmpfilename
285 # undefined variable causes a WARNING
286 cat > $tmpfilename <<EOF
287 (declaim (muffle-conditions warning))
288 (declaim (unmuffle-conditions style-warning))
291 expect_clean_compile
$tmpfilename
293 # top level LOCALLY behaves nicely
294 cat > $tmpfilename <<EOF
296 (declare (muffle-conditions warning))
299 expect_clean_compile
$tmpfilename
301 cat > $tmpfilename <<EOF
303 (declare (muffle-conditions warning))
307 expect_failed_compile
$tmpfilename
309 cat > $tmpfilename <<EOF
310 (declaim (optimize debug))
312 (declare (muffle-conditions warning))
316 expect_failed_compile
$tmpfilename
318 cat > $tmpfilename <<EOF
320 (locally (declare (muffle-conditions warning))
324 expect_failed_compile
$tmpfilename
326 # This should fail, and fail nicely -- not eg. loop trying to dump
327 # references to the unbound variable.
328 cat > $tmpfilename <<EOF
329 (defmacro macro-with-unbound-variables (foo)
332 (macro-with-unbound-variables 'xxx)
334 expect_failed_compile
$tmpfilename
336 # This should fail, as the MAKE-LOAD-FORM must be used for
337 # externalizing conditions, and the method for CONDITION must signal
339 cat > $tmpfilename <<EOF
340 (defvar *oops* #.(make-condition 'condition))
342 expect_failed_compile
$tmpfilename
344 # This should fail, as the MAKE-LOAD-FORM must be used for objects,
345 # and the method for STANDARD.OBJECT is required to signal an error.
346 cat > $tmpfilename <<EOF
347 (defvar *oops* #.(make-instance 'standard-object))
349 expect_failed_compile
$tmpfilename
351 # This should be clean
352 cat > $tmpfilename <<EOF
353 (defvar *string* (make-string 10 :element-type 'base-char))
355 expect_clean_compile
$tmpfilename
357 # This should style-warn (but not warn or otherwise fail) as the call
358 # to FORMAT has too many arguments, which is bad style but not
360 cat > $tmpfilename <<EOF
362 (format nil "abc~~def" a b))
364 expect_warned_compile
$tmpfilename
366 # Tests that destructive-functions on known-constant data cause
367 # compile-time warnings.
368 cat > $tmpfilename <<EOF
369 (let ((string "foo"))
371 (setf string "bar")))
373 expect_clean_compile
$tmpfilename
375 cat > $tmpfilename <<EOF
380 expect_clean_compile
$tmpfilename
382 cat > $tmpfilename <<EOF
387 expect_clean_compile
$tmpfilename
389 cat > $tmpfilename <<EOF
390 (let ((string "foo"))
392 (replace string "bar")))
394 expect_failed_compile
$tmpfilename
396 cat > $tmpfilename <<EOF
398 (setf (char "bar" 0) #\1))
400 expect_failed_compile
$tmpfilename
402 cat > $tmpfilename <<EOF
403 (let ((foo '(1 2 3)))
407 expect_failed_compile
$tmpfilename
409 cat > $tmpfilename <<EOF
414 expect_failed_compile
$tmpfilename
416 cat > $tmpfilename <<EOF
417 (declaim (optimize (speed 3) (space 0) (safety 0)))
422 expect_clean_compile
$tmpfilename
424 cat > $tmpfilename <<EOF
428 expect_clean_compile
$tmpfilename
430 cat > $tmpfilename <<EOF
431 (eval-when (:compile-toplevel :load-toplevel :execute)
433 (defmethod make-load-form ((foo foox) &optional env)
434 (declare (ignore env))
439 expect_clean_compile
$tmpfilename
441 cat > $tmpfilename <<EOF
442 (defun something (x) x)
444 (defun something-more (x) x)
446 expect_aborted_compile
$tmpfilename
448 cat > $tmpfilename <<EOF
451 expect_clean_cload
$tmpfilename
453 cat > $tmpfilename <<EOF
454 (defconstant cl-package (find-package :cl))
455 (defun cl-symbol-p (x)
456 (eq (symbol-package x) cl-package))
458 expect_clean_cload
$tmpfilename
460 cat > $tmpfilename <<EOF
461 (and (eval-when (:compile-toplevel) (error "oops AND")))
462 (or (eval-when (:compile-toplevel) (error "oops OR")))
463 (cond (t (eval-when (:compile-toplevel) (error "oops COND"))))
465 expect_clean_cload
$tmpfilename
467 # Test correct fasl-dumping of literals in arglist defaulting.
469 cat > $tmpfilename <<EOF
470 (in-package :cl-user)
472 ;; These are CLHS examples from the dictionary entry for MAKE-LOAD-FORM.
473 (eval-when (:compile-toplevel :load-toplevel :execute)
474 (defstruct my-struct a b c)
475 (defmethod make-load-form ((s my-struct) &optional environment)
476 (make-load-form-saving-slots s :environment environment))
477 (defclass my-class ()
478 ((x :initarg :x :reader obj-x)
479 (y :initarg :y :reader obj-y)
480 (dist :accessor obj-dist)))
481 (defmethod make-load-form ((self my-class) &optional environment)
482 (make-load-form-saving-slots self
484 :environment environment)))
486 (defun bar1 (&optional (x #.(make-my-struct)))
489 (defun bar2 (&optional (x #.(make-instance 'my-class)))
492 ;; Packages are externalizable.
493 (defun bar3 (&optional (x #.*package*))
496 (assert (typep (bar1) 'my-struct))
497 (assert (typep (bar2) 'my-class))
498 (assert (eq (bar3) *package*))
501 expect_clean_cload
$tmpfilename
503 cat > $tmpfilename <<EOF
504 (in-package :cl-user)
505 (defmacro foo () (error "ERROR at macroexpansion time."))
508 expect_condition_during_compile sb-c
:compiler-error
$tmpfilename
510 cat > $tmpfilename <<EOF
511 (eval-when (:compile-toplevel)
512 (error "ERROR within EVAL-WHEN."))
514 expect_condition_during_compile simple-error
$tmpfilename
516 cat > $tmpfilename <<EOF
517 (defun slot-name-incf (s)
518 (with-slots (no-such-slot) s
519 (incf no-such-slot)))
521 expect_clean_cload
$tmpfilename
523 cat > $tmpfilename <<EOF
524 (in-package :cl-user)
527 (declare (muffle-conditions warning))
529 (declare (type double-float em))
531 (setf em (float (1+ i))))))
533 expect_clean_compile
$tmpfilename
535 cat > $tmpfilename <<EOF
536 (in-package :cl-user)
539 (declare (muffle-conditions warning))
541 (declare (values fixnum))
545 expect_clean_compile
$tmpfilename
547 cat > $tmpfilename <<EOF
548 (in-package :cl-user)
551 (declare (muffle-conditions warning)
552 (type (vector (mod 7) 1) x))
556 expect_clean_compile
$tmpfilename
558 cat > $tmpfilename <<EOF
559 (in-package :cl-user)
561 (declaim (notinline foo))
562 (let ((i 0)) (defun foo (x) (incf i x)))
563 (defun bar (x) (foo x))
565 fail_on_condition_during_compile sb-ext
:compiler-note
$tmpfilename
567 cat > $tmpfilename <<EOF
568 (in-package :cl-user)
570 (eval-when (:compile-toplevel :load-toplevel :execute)
571 (defclass subclass (superclass) ((zslot2 :initarg :zslot2 :accessor zslot2))))
573 (eval-when (:compile-toplevel :load-toplevel :execute)
574 (defclass superclass () ((c :initarg c :accessor c))))
576 (eval-when (:compile-toplevel :load-toplevel :execute)
577 (sb-kernel::%invalidate-layout (sb-pcl::class-wrapper (find-class 'subclass))))
579 ;; This test file is weird. It expects to see warnings from a COMPILE inside
580 ;; a method body that is compiled (and not necessarily invoked).
581 ;; To force the warnings to happen, we have to force the method to get called,
582 ;; which we can do by asking a SUBTYPEP question.
583 (eval-when (:compile-toplevel :load-toplevel :execute)
584 (defmethod sb-mop:finalize-inheritance :after (class)
585 (eval '(defmethod z (x) (abcde)))
586 (funcall (compile nil '(lambda () (defun zz (x) (defgh))))))
587 (assert (not (sb-kernel:csubtypep (sb-kernel:specifier-type 'subclass)
588 (sb-kernel:specifier-type 'condition)))))
590 (defun subclass-p (x)
593 expect_warned_compile
$tmpfilename
595 cat > $tmpfilename <<EOF
596 (let ((a (load-time-value (funcall (lambda () 128)))))
601 expect_clean_cload
$tmpfilename
603 # Test compiler warning generation for unbound variables from type declaration...
604 cat > $tmpfilename <<EOF
606 (declare (type vector baz))
609 expect_failed_compile
$tmpfilename
611 # ... extent declaration ...
612 cat > $tmpfilename <<EOF
614 (declare (type (mod 32) n))
615 (let ((vect (make-array n :element-type 'fixnum)))
616 (declare (dynamic-extent vec))
619 expect_failed_compile
$tmpfilename
622 cat > $tmpfilename <<EOF
625 expect_failed_compile
$tmpfilename