1 ;;;; DEFGLOBAL and related tests
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
12 ;;;; more information.
14 (proclaim '(special *foo*))
17 (let ((*evaluator-mode* :interpret))
20 (defun unbound-marker ()
21 (sb-c::%primitive sb-c:make-unbound-marker))
23 (defun assert-foo-not-checked (fun)
24 (let* ((marker (unbound-marker))
26 (assert (eq marker (funcall fun)))))
28 (defun assert-foo-checked (fun)
29 (let* ((marker (unbound-marker))
35 (assert (eq '*foo* (cell-error-name e)))
38 (with-test (:name :unbound-cannot-be-always-bound)
41 (proclaim '(sb-ext:always-bound *foo*))
45 (proclaim '(sb-ext:always-bound *foo*))
48 (declare (optimize (safety 3)))
51 (with-test (:name :always-bound-elides-boundness-checking)
52 (assert-foo-not-checked #'foo-safe))
54 (with-test (:name :cannot-unbind-always-bound)
60 (defun can-globalize-p (x)
62 (progn (proclaim `(sb-ext:global ,x)) t)
65 (with-test (:name :cannot-proclaim-special-global)
66 (assert (not (can-globalize-p '*foo*))))
68 (define-symbol-macro sm 42)
69 (with-test (:name :cannot-proclaim-symbol-macro-global)
70 (assert (not (can-globalize-p 'sm))))
73 (with-test (:name :cannot-proclaim-constant-global)
74 (assert (not (can-globalize-p 'con))))
76 (with-test (:name :proclaim-global)
77 (assert (can-globalize-p '.bar.)))
80 (with-test (:name :global-does-not-imply-always-bound)
85 (cell-error-name e))))))
87 (with-test (:name :set-global)
91 (assert (= 123 (bar1))))
93 (with-test (:name :cannot-bind-globals)
96 (eval* '(let ((.bar. 6)) .bar.))
100 (funcall (compile nil `(lambda ()
101 (let ((.bar. 5)) .bar.))))
104 (with-test (:name :cannot-define-globals-as-symmacs)
107 (eval* '(define-symbol-macro .bar. 0))
111 (eval* `(symbol-macrolet ((.bar. 11)) .bar.))
115 (funcall (compile nil `(lambda ()
116 (symbol-macrolet ((.bar. 11)) .bar.))))
119 ;;; Cannot proclaim or declare a global as special
120 (with-test (:name :cannot-declare-global-special)
122 (handler-case (proclaim '(special .bar. 666))
126 (funcall (compile nil `(lambda ()
127 (declare (special .bar.))
131 (handler-case (eval `(locally (declare (special .bar.)) .bar.))
134 ;;; Dead globals get bound checks
135 (declaim (global this-is-unbound))
136 (with-test (:name :dead-unbound-global)
139 (funcall (compile nil
146 (defun compile-form (form)
147 (let* ((lisp "defglobal-impure-tmp.lisp"))
150 (with-open-file (f lisp :direction :output)
152 (multiple-value-bind (fasl warn fail) (compile-file lisp)
153 (declare (ignore warn))
155 (error "compiling ~S failed" form))
157 (ignore-errors (delete-file lisp)))))
160 (with-test (:name :defconstant-evals)
162 (fasl (compile-form `(defglobal .counter-1. (incf *counter*)))))
163 (assert (= 1 *counter*))
164 (assert (= 1 (symbol-value '.counter-1.)))
165 (assert (eq :global (sb-int:info :variable :kind '.counter-1.)))
168 (ignore-errors (delete-file fasl)))
169 (assert (= 1 *counter*))
170 (assert (= 1 (symbol-value '.counter-1.))))
172 (set '.counter-2. :bound)
174 (fasl (compile-form `(defglobal .counter-2. (incf *counter*)))))
175 (assert (= 0 *counter*))
176 (assert (eq :bound (symbol-value '.counter-2.)))
177 (assert (eq :global (sb-int:info :variable :kind '.counter-2.)))
180 (ignore-errors (delete-file fasl)))
181 (assert (= 0 *counter*))
182 (assert (eq :bound (symbol-value '.counter-2.))))
184 ;; This is a *really* dirty trick...
186 (fasl (let ((.counter-3. :nasty))
187 (declare (special .counter-3.))
188 (compile-form `(defglobal .counter-3. (incf *counter*))))))
189 (assert (= 0 *counter*))
190 (assert (not (boundp '.counter-3.)))
191 (assert (eq :global (sb-int:info :variable :kind '.counter-3.)))
194 (ignore-errors (delete-file fasl)))
195 (assert (= 1 *counter*))
196 (assert (= 1 (symbol-value '.counter-3.)))))
198 (with-test (:name :defglobal-refers-to-defglobal)
199 (let ((fasl (compile-form `(progn
200 (defglobal **global-1** :fii)
201 (defglobal **global-2** **global-1**)))))
203 (assert (eq (symbol-value '**global-1**) (symbol-value '**global-2**)))
204 (assert (eq :fii (symbol-value '**global-1**)))))