0.8.21.38: fix bug 211e
[sbcl.git] / tests / compiler.impure.lisp
index 9a2aed6..5baf7d1 100644 (file)
 ;;; bug 194, fixed in part by APD "more strict type checking" patch
 ;;; (sbcl-devel 2002-08-07)
 (progn
-  #+nil ; FIXME: still broken in 0.7.7.19 (after patch)
   (multiple-value-bind (result error)
       (ignore-errors (multiple-value-prog1 (progn (the real '(1 2 3)))))
     (assert (null result))
     (assert (typep error 'type-error)))
-  #+nil ; FIXME: still broken in 0.7.7.19 (after patch)
   (multiple-value-bind (result error)
       (ignore-errors (the real '(1 2 3)))
     (assert (null result))
     (assert (typep error 'type-error))))
+
+(defun bug194d ()
+  (null (ignore-errors
+          (let ((arg1 1)
+                (arg2 (identity (the real #(1 2 3)))))
+            (if (< arg1 arg2) arg1 arg2)))))
+(assert (eq (bug194d) t))
+
 \f
 ;;; BUG 48a. and b. (symbol-macrolet handling), fixed by Eric Marsden
 ;;; and Raymond Toy for CMUCL, fix ported for sbcl-0.7.6.18.
 (multiple-value-bind (function warnings-p failure-p)
-    (compile nil '(lambda () (symbol-macrolet ((t nil)) t)))
+    (compile nil '(lambda ()
+                   ;; not interested in the package lock violation here
+                   (declare (sb-ext:disable-package-locks t))
+                   (symbol-macrolet ((t nil)) t)))
   (assert failure-p)
   (assert (raises-error? (funcall function) program-error)))
 (multiple-value-bind (function warnings-p failure-p)
     (compile nil
             '(lambda ()
+               ;; not interested in the package lock violation here
+               (declare (sb-ext:disable-package-locks *standard-input*))
                (symbol-macrolet ((*standard-input* nil))
                  *standard-input*)))
   (assert failure-p)
   (assert (raises-error? (funcall function) program-error)))
-#||
-BUG 48c, not yet fixed:
 (multiple-value-bind (function warnings-p failure-p)
     (compile nil '(lambda () (symbol-macrolet ((s nil)) (declare (special s)) s)))
   (assert failure-p)
   (assert (raises-error? (funcall function) program-error)))
-||#
 \f
 ;;; bug 120a: Turned out to be constraining code looking like (if foo
 ;;; <X> <X>) where <X> was optimized by the compiler to be the exact
@@ -586,9 +594,9 @@ BUG 48c, not yet fixed:
                         `(lambda (f)
                            (declare (optimize (speed 2) (safety ,policy1)))
                            (multiple-value-list
-                            (the (values (integer 2 3) t)
+                            (the (values (integer 2 3) t &optional)
                               (locally (declare (optimize (safety ,policy2)))
-                                (the (values t (single-float 2f0 3f0))
+                                (the (values t (single-float 2f0 3f0) &optional)
                                   (funcall f)))))))
                (lambda () (values x y)))
     (type-error (error)
@@ -602,7 +610,6 @@ BUG 48c, not yet fixed:
 (assert (equal (check-embedded-thes 0 1  :a 3.5f0) '(:a 3.5f0)))
 (assert (typep (check-embedded-thes 0 1  2 2.5d0) 'type-error))
 
-#+nil
 (assert (equal (check-embedded-thes 3 0  2 :a) '(2 :a)))
 (assert (typep (check-embedded-thes 3 0  4 2.5f0) 'type-error))
 
@@ -613,7 +620,6 @@ BUG 48c, not yet fixed:
 (assert (equal (check-embedded-thes 3 3  2 2.5f0) '(2 2.5f0)))
 (assert (typep (check-embedded-thes 3 3  0 2.5f0) 'type-error))
 (assert (typep (check-embedded-thes 3 3  2 3.5f0) 'type-error))
-
 \f
 ;;; INLINE inside MACROLET
 (declaim (inline to-be-inlined))
@@ -724,10 +730,14 @@ BUG 48c, not yet fixed:
 ;;; COERCE got its own DEFOPTIMIZER which has to reimplement most of
 ;;; SPECIFIER-TYPE-NTH-ARG.  For a while, an illegal type would throw
 ;;; you into the debugger on compilation.
-(defun coerce-defopt (x)
+(defun coerce-defopt1 (x)
   ;; illegal, but should be compilable.
   (coerce x '(values t)))
-(assert (null (ignore-errors (coerce-defopt 3))))
+(defun coerce-defopt2 (x)
+  ;; illegal, but should be compilable.
+  (coerce x '(values t &optional)))
+(assert (null (ignore-errors (coerce-defopt1 3))))
+(assert (null (ignore-errors (coerce-defopt2 3))))
 \f
 ;;; Oops.  In part of the (CATCH ..) implementation of DEBUG-RETURN,
 ;;; it was possible to confuse the type deriver of the compiler
@@ -763,6 +773,157 @@ BUG 48c, not yet fixed:
   (when x
     (assert (= (funcall (compile nil x) 1) 2))))
 
+;;;
+(defun bug192b (i)
+  (dotimes (j i)
+    (declare (type (mod 4) i))
+    (unless (< i 5)
+      (print j))))
+(assert (raises-error? (bug192b 6) type-error))
+
+(defun bug192c (x y)
+  (locally (declare (type fixnum x y))
+    (+ x (* 2 y))))
+(assert (raises-error? (bug192c 1.1 2) type-error))
+
+(assert (raises-error? (progn (the real (list 1)) t) type-error))
+
+(defun bug236 (a f)
+  (declare (optimize (speed 2) (safety 0)))
+  (+ 1d0
+     (the double-float
+       (multiple-value-prog1
+           (svref a 0)
+         (unless f (return-from bug236 0))))))
+(assert (eql (bug236 #(4) nil) 0))
+
+;;; Bug reported by reported by rif on c.l.l 2003-03-05
+(defun test-type-of-special-1 (x)
+  (declare (special x)
+           (fixnum x)
+           (optimize (safety 3)))
+  (list x))
+(defun test-type-of-special-2 (x)
+  (declare (special x)
+           (fixnum x)
+           (optimize (safety 3)))
+  (list x (setq x (/ x 2)) x))
+(assert (raises-error? (test-type-of-special-1 3/2) type-error))
+(assert (raises-error? (test-type-of-special-2 3) type-error))
+(assert (equal (test-type-of-special-2 8) '(8 4 4)))
+
+;;; bug which existed in 0.8alpha.0.4 for several milliseconds before
+;;; APD fixed it in 0.8alpha.0.5
+(defun frob8alpha04 (x y)
+  (+ x y))
+(defun baz8alpha04 (this kids)
+  (flet ((n-i (&rest rest)
+          ;; Removing the #+NIL here makes the bug go away.
+          #+nil (format t "~&in N-I REST=~S~%" rest)
+          (apply #'frob8alpha04 this rest)))
+    (n-i kids)))
+;;; failed in 0.8alpha.0.4 with "The value 13 is not of type LIST."
+(assert (= (baz8alpha04 12 13) 25))
+
+;;; evaluation order in structure slot writers
+(defstruct sswo
+  a b)
+(let* ((i 0)
+       (s (make-sswo :a (incf i) :b (incf i)))
+       (l (list s :v)))
+  (assert (= (sswo-a s) 1))
+  (assert (= (sswo-b s) 2))
+  (setf (sswo-a (pop l)) (pop l))
+  (assert (eq l nil))
+  (assert (eq (sswo-a s) :v)))
+
+(defun bug249 (x)
+  (flet ((bar (y)
+           (declare (fixnum y))
+           (incf x)))
+    (list (bar x) (bar x) (bar x))))
+
+(assert (raises-error? (bug249 1.0) type-error))
+
+;;; bug reported by ohler on #lisp 2003-07-10
+(defun bug-ohler-2003-07-10 (a b)
+  (declare (optimize (speed 0) (safety 3) (space 0)
+                     (debug 1) (compilation-speed 0)))
+  (adjoin a b))
+
+;;; bug reported by Doug McNaught on sbcl-devel 2003-09-14:
+;;; COMPILE-FILE did not bind *READTABLE*
+(let* ((source "bug-doug-mcnaught-20030914.lisp")
+       (fasl (compile-file-pathname source)))
+  (labels ((check ()
+             (assert (null (get-macro-character #\]))))
+           (full-check ()
+             (check)
+             (assert (typep *bug-doug-mcnaught-20030914*
+                            '(simple-array (unsigned-byte 4) (*))))
+             (assert (equalp *bug-doug-mcnaught-20030914* #(1 2 3)))
+             (makunbound '*bug-doug-mcnaught-20030914*)))
+    (compile-file source)
+    (check)
+    (load fasl)
+    (full-check)
+    (load source)
+    (full-check)
+    (delete-file fasl)))
+\f
+(defun expt-derive-type-bug (a b)
+  (unless (< a b)
+    (truncate (expt a b))))
+(assert (equal (multiple-value-list (expt-derive-type-bug 1 1))
+              '(1 0)))
+
+;;; Problems with type checking in functions with EXPLICIT-CHECK
+;;; attribute (reported by Peter Graves)
+(loop for (fun . args) in '((= a) (/= a)
+                            (< a) (<= a) (> a) (>= a))
+      do (assert (raises-error? (apply fun args) type-error)))
+
+(defclass broken-input-stream (sb-gray:fundamental-input-stream) ())
+(defmethod sb-gray:stream-read-char ((stream broken-input-stream))
+  (throw 'break :broken))
+(assert (eql (block return
+               (handler-case
+                   (catch 'break
+                     (funcall (eval ''peek-char)
+                              1 (make-instance 'broken-input-stream))
+                     :test-broken)
+                 (type-error (c)
+                   (return-from return :good))))
+             :good))
+\f
+;;;; MUFFLE-CONDITIONS test (corresponds to the test in the manual)
+(defvar *compiler-note-count* 0)
+#-(or alpha x86-64) ; FIXME: make a better test!
+(handler-bind ((sb-ext:compiler-note (lambda (c)
+                                      (declare (ignore c))
+                                      (incf *compiler-note-count*))))
+  (let ((fun
+        (compile nil
+                 '(lambda (x)
+                   (declare (optimize speed) (fixnum x))
+                   (declare (sb-ext:muffle-conditions sb-ext:compiler-note))
+                   (values (* x 5) ; no compiler note from this
+                    (locally
+                      (declare (sb-ext:unmuffle-conditions sb-ext:compiler-note))
+                      ;; this one gives a compiler note
+                      (* x -5)))))))
+    (assert (= *compiler-note-count* 1))
+    (assert (equal (multiple-value-list (funcall fun 1)) '(5 -5)))))
+\f
+(handler-case
+    (eval '(flet ((%f (&key) nil)) (%f nil nil)))
+  (error (c) :good)
+  (:no-error (val) (error "no error: ~S" val)))
+(handler-case
+    (eval '(labels ((%f (&key x) x)) (%f nil nil)))
+  (error (c) :good)
+  (:no-error (val) (error "no error: ~S" val)))
+\f
 ;;;; tests not in the problem domain, but of the consistency of the
 ;;;; compiler machinery itself
 
@@ -829,5 +990,51 @@ BUG 48c, not yet fixed:
          (grovel-results name))))))
 (identify-suspect-vops)
 \f
+;;;; tests for compiler output
+(let* ((*error-output* (make-broadcast-stream))
+       (output (with-output-to-string (*standard-output*)
+                (compile-file "compiler-output-test.lisp" 
+                              :print nil :verbose nil))))
+  (print output)
+  (assert (zerop (length output))))
+
+;;;; bug 305: INLINE/NOTINLINE causing local ftype to be lost
+
+(define-condition optimization-error (error) ())
+
+(labels ((compile-lambda (type sense)
+          (handler-bind ((compiler-note (lambda (_)
+                                          (declare (ignore _))
+                                          (error 'optimization-error))))
+            (values
+             (compile 
+              nil
+              `(lambda ()
+                 (declare 
+                  ,@(when type '((ftype (function () (integer 0 10)) bug-305)))
+                  (,sense bug-305)
+                  (optimize speed))
+                 (1+ (bug-305))))
+             nil)))
+        (expect-error (sense)
+          (multiple-value-bind (f e)  (ignore-errors (compile-lambda nil sense))
+            (assert (not f))
+            (assert (typep e 'optimization-error))))
+        (expect-pass (sense)
+          (multiple-value-bind (f e)  (ignore-errors (compile-lambda t sense))
+            (assert f)
+            (assert (not e)))))
+  (expect-error 'inline)
+  (expect-error 'notinline)
+  (expect-pass 'inline)
+  (expect-pass 'notinline))
+
+;;; bug 211e: bogus style warning from duplicated keyword argument to
+;;; a local function.
+(handler-bind ((style-warning #'error))
+  (let ((f (compile nil '(lambda () (flet ((foo (&key y) (list y)))
+                                     (list (foo :y 1 :y 2)))))))
+    (assert (equal '((1)) (funcall f)))))
+
 ;;; success
 (quit :unix-status 104)