X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fcompiler.impure.lisp;h=f36f860bcffcee1aeb6f7791ca9b10e3d2148372;hb=3a10f894e7867fa2c27a3af05380abc3247f728d;hp=1d5ce41171ca37b11a51d7910bb027507f49cf5d;hpb=7e6a733d8decb72a778323d6dba4dcc5699a91fc;p=sbcl.git diff --git a/tests/compiler.impure.lisp b/tests/compiler.impure.lisp index 1d5ce41..f36f860 100644 --- a/tests/compiler.impure.lisp +++ b/tests/compiler.impure.lisp @@ -15,9 +15,8 @@ ;;;; absolutely no warranty. See the COPYING and CREDITS files for ;;;; more information. -(cl:in-package :cl-user) - (load "assertoid.lisp") +(use-package "ASSERTOID") ;;; Old CMU CL code assumed that the names of "keyword" arguments are ;;; necessarily self-evaluating symbols, but ANSI Common Lisp allows @@ -405,21 +404,22 @@ BUG 48c, not yet fixed: (declare (ignore result)) (assert (typep condition 'type-error))) -;;; bug 110: the compiler flushed the argument type test and the default -;;; case in the cond. - -(defun bug110 (x) - (declare (optimize (safety 2) (speed 3))) - (declare (type (or string stream) x)) - (cond ((typep x 'string) 'string) - ((typep x 'stream) 'stream) - (t - 'none))) - -(multiple-value-bind (result condition) - (ignore-errors (bug110 0)) - (declare (ignore result)) - (assert (typep condition 'type-error))) +;;;; bug 110: the compiler flushed the argument type test and the default +;;;; case in the cond. +; +;(locally (declare (optimize (safety 3) (speed 2))) +; (defun bug110 (x) +; (declare (optimize (safety 2) (speed 3))) +; (declare (type (or string stream) x)) +; (cond ((typep x 'string) 'string) +; ((typep x 'stream) 'stream) +; (t +; 'none)))) +; +;(multiple-value-bind (result condition) +; (ignore-errors (bug110 0)) +; (declare (ignore result)) +; (assert (typep condition 'type-error))) ;;; bug 202: the compiler failed to compile a function, which derived ;;; type contradicted declared. @@ -578,6 +578,218 @@ BUG 48c, not yet fixed: ;;; (fix provided by Matthew Danish) on sbcl-devel (assert (null (ignore-errors (defmacro bug172 (&rest rest foo) `(list ,rest ,foo))))) + +;;; embedded THEs +(defun check-embedded-thes (policy1 policy2 x y) + (handler-case + (funcall (compile nil + `(lambda (f) + (declare (optimize (speed 2) (safety ,policy1))) + (multiple-value-list + (the (values (integer 2 3) t) + (locally (declare (optimize (safety ,policy2))) + (the (values t (single-float 2f0 3f0)) + (funcall f))))))) + (lambda () (values x y))) + (type-error (error) + error))) + +(assert (equal (check-embedded-thes 0 0 :a :b) '(:a :b))) + +(assert (equal (check-embedded-thes 0 3 :a 2.5f0) '(:a 2.5f0))) +(assert (typep (check-embedded-thes 0 3 2 3.5f0) 'type-error)) + +(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)) + +(assert (equal (check-embedded-thes 1 0 4 :b) '(4 :b))) +(assert (typep (check-embedded-thes 1 0 1.0 2.5f0) 'type-error)) + + +(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)) + + +;;; INLINE inside MACROLET +(declaim (inline to-be-inlined)) +(macrolet ((def (x) `(defun ,x (y) (+ y 1)))) + (def to-be-inlined)) +(defun call-inlined (z) + (to-be-inlined z)) +(assert (= (call-inlined 3) 4)) +(macrolet ((frob (x) `(+ ,x 3))) + (defun to-be-inlined (y) + (frob y))) +(assert (= (call-inlined 3) + ;; we should have inlined the previous definition, so the + ;; new one won't show up yet. + 4)) +(defun call-inlined (z) + (to-be-inlined z)) +(assert (= (call-inlined 3) 6)) +(defun to-be-inlined (y) + (+ y 5)) +(assert (= (call-inlined 3) 6)) + +;;; DEFINE-COMPILER-MACRO to work as expected, not via weird magical +;;; IR1 pseudo-:COMPILE-TOPLEVEL handling +(defvar *bug219-a-expanded-p* nil) +(defun bug219-a (x) + (+ x 1)) +(define-compiler-macro bug219-a (&whole form y) + (setf *bug219-a-expanded-p* t) + (if (constantp y) + (+ (eval y) 2) + form)) +(defun bug219-a-aux () + (bug219-a 2)) +(assert (= (bug219-a-aux) + (if *bug219-a-expanded-p* 4 3))) +(defvar *bug219-a-temp* 3) +(assert (= (bug219-a *bug219-a-temp*) 4)) + +(defvar *bug219-b-expanded-p* nil) +(defun bug219-b-aux1 (x) + (when x + (define-compiler-macro bug219-b (y) + (setf *bug219-b-expanded-p* t) + `(+ ,y 2)))) +(defun bug219-b-aux2 (z) + (bug219-b z)) +(assert (not *bug219-b-expanded-p*)) +(assert (raises-error? (bug219-b-aux2 1) undefined-function)) +(bug219-b-aux1 t) +(defun bug219-b-aux2 (z) + (bug219-b z)) +(defun bug219-b (x) + x) +(assert (= (bug219-b-aux2 1) + (if *bug219-b-expanded-p* 3 1))) + +;;; bug 224: failure in unreachable code deletion +(defmacro do-optimizations (&body body) + `(dotimes (.speed. 4) + (dotimes (.space. 4) + (dotimes (.debug. 4) + (dotimes (.compilation-speed. 4) + (proclaim `(optimize (speed , .speed.) (space , .space.) + (debug , .debug.) + (compilation-speed , .compilation-speed.))) + ,@body))))) + +(do-optimizations + (compile nil + (read-from-string + "(lambda () (#:localy (declare (optimize (safety 3))) + (ignore-errors (progn (values-list (car (list '(1 . 2)))) t))))"))) + +(do-optimizations + (compile nil '(lambda () + (labels ((ext () + (tagbody + (labels ((i1 () (list (i2) (i2))) + (i2 () (list (int) (i1))) + (int () (go :exit))) + (list (i1) (i1) (i1))) + :exit (return-from ext) + ))) + (list (error "nih") (ext) (ext)))))) + +(do-optimizations + (compile nil '(lambda (x) (let ((y (error ""))) (list x y))))) + +;;; bug 223: invalid moving of global function name referencing +(defun bug223-int (n) + `(int ,n)) + +(defun bug223-wrap () + (let ((old #'bug223-int)) + (setf (fdefinition 'bug223-int) + (lambda (n) + (assert (> n 0)) + `(ext ,@(funcall old (1- n))))))) +(compile 'bug223-wrap) + +(assert (equal (bug223-int 4) '(int 4))) +(bug223-wrap) +(assert (equal (bug223-int 4) '(ext int 3))) +(bug223-wrap) +(assert (equal (bug223-int 4) '(ext ext int 2))) + +;;; 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) + ;; illegal, but should be compilable. + (coerce x '(values t))) +(assert (null (ignore-errors (coerce-defopt 3)))) + +;;; Oops. In part of the (CATCH ..) implementation of DEBUG-RETURN, +;;; it was possible to confuse the type deriver of the compiler +;;; sufficiently that compiler invariants were broken (explained by +;;; APD sbcl-devel 2003-01-11). + +;;; WHN's original report +(defun debug-return-catch-break1 () + (with-open-file (s "/tmp/foo" + :direction :output + :element-type (list + 'signed-byte + (1+ + (integer-length most-positive-fixnum)))) + (read-byte s) + (read-byte s) + (read-byte s) + (read-byte s))) + +;;; APD's simplified test case +(defun debug-return-catch-break2 (x) + (declare (type (vector (unsigned-byte 8)) x)) + (setq *y* (the (unsigned-byte 8) (aref x 4)))) + +;;; FUNCTION-LAMBDA-EXPRESSION should return something that's COMPILE +;;; can understand. Here's a simple test for that on a function +;;; that's likely to return a hairier list than just a lambda: +(macrolet ((def (fn) `(progn + (declaim (inline ,fn)) + (defun ,fn (x) (1+ x))))) + (def bug228)) +(let ((x (function-lambda-expression #'bug228))) + (when x + (assert (= (funcall (compile nil x) 1) 2)))) + +;;; 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)) ;;;; tests not in the problem domain, but of the consistency of the ;;;; compiler machinery itself