Skip to content

Commit

Permalink
0.7.7.19:
Browse files Browse the repository at this point in the history
	corrected BUGS 35 entry as per APD sbcl-devel 2002-08-07
	merged APD "more strict type checking" patch (sbcl-devel
		2002-08-08), fixing bug 192a ("free type declarations
		are promises") and one of the problems lumped into
		bug 194 (the case of type checking getting lost
		when THE occurs inside MULTIPLE-VALUE-PROG1)
  • Loading branch information
William Harold Newman committed Sep 9, 2002
1 parent dae7439 commit fb91e19
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 70 deletions.
81 changes: 37 additions & 44 deletions BUGS
@@ -1,4 +1,4 @@
tREPORTING BUGS
REPORTING BUGS

Bugs can be reported on the help mailing list
sbcl-help@lists.sourceforge.net
Expand Down Expand Up @@ -183,7 +183,8 @@ WORKAROUND:
then executing
(FOO 1.5)
will cause the INTEGERP case to be selected, giving bogus output a la
exactly 1.33..
exactly 2.5
(or (FOO 1000.5), "exactly 1001.5")
This violates the "declarations are assertions" principle.
According to the ANSI spec, in the section "System Class FUNCTION",
this is a case of "lying to the compiler", but the lying is done
Expand Down Expand Up @@ -1280,17 +1281,9 @@ WORKAROUND:
lists and &KEY arguments) do not signal errors when they should.

192: "Python treats free type declarations as promises."
a. original report by Alexey Dejneka (on sbcl-devel 2002-08-26):
(declaim (optimize (speed 0) (safety 3)))
(defun f (x)
(declare (real x))
(+ x
(locally (declare (single-float x))
(sin x))))
Now (F NIL) correctly gives a type error, but (F 100) gives
a segmentation violation.
b. same fundamental problem in a different way, easy to stumble
across if you mistype and declare the wrong index in
b. What seemed like the same fundamental problem as bug 192a, but
was not fixed by the same (APD "more strict type checking
sbcl-devel 2002-08-97) patch:
(DOTIMES (I ...) (DOTIMES (J ...) (DECLARE ...) ...)):
(declaim (optimize (speed 1) (safety 3)))
(defun trust-assertion (i)
Expand Down Expand Up @@ -1320,8 +1313,31 @@ WORKAROUND:
bad argument value is).

194: "no error from (THE REAL '(1 2 3)) in some cases"
(Actually this entry is probably two separate bugs, as
Alexey Dejneka commented on sbcl-devel 2002-09-03:)
fixed parts:
a. In sbcl-0.7.7.9,
(multiple-value-prog1 (progn (the real '(1 2 3))))
returns (1 2 3) instead of signalling an error. This was fixed by
APD's "more strict type checking patch", but although the fixed
code (in sbcl-0.7.7.19) works (signals TYPE-ERROR) interactively,
it's difficult to write a regression test for it, because
(IGNORE-ERRORS (MULTIPLE-VALUE-PROG1 (PROGN (THE REAL '(1 2 3)))))
still returns (1 2 3).
still-broken parts:
b. (IGNORE-ERRORS (MULTIPLE-VALUE-PROG1 (PROGN (THE REAL '(1 2 3)))))
returns (1 2 3). (As above, this shows up when writing regression
tests for fixed-ness of part a.)
c. Also in sbcl-0.7.7.9, (IGNORE-ERRORS (THE REAL '(1 2 3))) => (1 2 3).
d. At the REPL,
(null (ignore-errors
(let ((arg1 1)
(arg2 (identity (the real #(1 2 3)))))
(if (< arg1 arg2) arg1 arg2))))
=> T
but putting the same expression inside (DEFUN FOO () ...),
(FOO) => NIL.
notes:
* Actually this entry is probably multiple bugs, as
Alexey Dejneka commented on sbcl-devel 2002-09-03:)
I don't think that placing these two bugs in one entry is
a good idea: they have different explanations. The second
(min 1 nil) is caused by flushing of unused code--IDENTITY
Expand All @@ -1330,35 +1346,12 @@ WORKAROUND:
for the result, it forgets about type assertion. The purpose
of IDENTITY is to save the restricted continuation from
inaccurate transformations.
In sbcl-0.7.7.9,
(multiple-value-prog1 (progn (the real '(1 2 3))))
returns (1 2 3) instead of signalling an error. Also in sbcl-0.7.7.9,
a more complicated instance of this bug kept
(IGNORE-ERRORS (MIN '(1 2 3))) from returning NIL as it should when
the MIN source transform expanded to (THE REAL '(1 2 3)), because
(IGNORE-ERRORS (THE REAL '(1 2 3))) returns (1 2 3).
Alexey Dejneka pointed out that
(IGNORE-ERRORS (IDENTITY (THE REAL '(1 2 3)))) works as it should.
(IGNORE-ERRORS (VALUES (THE REAL '(1 2 3)))) also works as it should.
Perhaps this is another case of VALUES type intersections behaving
in non-useful ways?
When I (WHN) tried to use the VALUES trick to work around this bug
in the MIN source transform, it didn't work for
(assert (null (ignore-errors (min 1 #(1 2 3)))))
Hand-expanding the source transform, I get
(assert (null (ignore-errors
(let ((arg1 1)
(arg2 (identity (the real #(1 2 3)))))
(if (< arg1 arg2) arg1 arg2)))))
which fails (i.e. the assertion fails, because the IGNORE-ERRORS
doesn't report MIN signalling a type error). At the REPL
(null (ignore-errors
(let ((arg1 1)
(arg2 (identity (the real #(1 2 3)))))
(if (< arg1 arg2) arg1 arg2))))
=> T
but when this expression is used as the body of (DEFUN FOO () ...)
then (FOO)=>NIL.
* Alexey Dejneka pointed out that
(IGNORE-ERRORS (IDENTITY (THE REAL '(1 2 3))))
works as it should. Also
(IGNORE-ERRORS (VALUES (THE REAL '(1 2 3))))
works as it should. Perhaps this is another case of VALUES type
intersections behaving in non-useful ways?

195: "confusing reporting of not-a-REAL TYPE-ERRORs from THE REAL"
In sbcl-0.7.7.10, (THE REAL #(1 2 3)) signals a type error which
Expand Down
3 changes: 3 additions & 0 deletions NEWS
Expand Up @@ -1263,6 +1263,9 @@ changes in sbcl-0.7.8 relative to sbcl-0.7.7:
found).
* fixed bug 174: FORMAT's error message is slightly clearer when a
non-printing character is used in a format directive.
* fixed several bugs in compiler checking of type declarations, i.e.
violations of the Python "declarations are assertions" principle
(thanks to Alexey Dejneka)

planned incompatible changes in 0.7.x:
* When the profiling interface settles down, maybe in 0.7.x, maybe
Expand Down
16 changes: 10 additions & 6 deletions src/compiler/ir1-translators.lisp
Expand Up @@ -718,9 +718,9 @@
;;; We make this work by getting USE-CONTINUATION to do the unioning
;;; across COND branches. We can't do it here, since we don't know how
;;; many branches there are going to be.
(defun ir1ize-the-or-values (type cont lexenv name)
(defun ir1ize-the-or-values (type cont lexenv place)
(declare (type continuation cont) (type lexenv lexenv))
(let* ((ctype (values-specifier-type type))
(let* ((ctype (if (typep type 'ctype) type (values-specifier-type type)))
(old-type (or (lexenv-find cont type-restrictions)
*wild-type*))
(intersects (values-types-equal-or-intersect old-type ctype))
Expand All @@ -734,10 +734,10 @@
(not (policy *lexenv*
(= inhibit-warnings 3)))) ;FIXME: really OK to suppress?
(compiler-warn
"The type ~S in ~S declaration conflicts with an ~
"The type ~S ~A conflicts with an ~
enclosing assertion:~% ~S"
(type-specifier ctype)
name
place
(type-specifier old-type)))
(make-lexenv :type-restrictions `((,cont . ,new))
:default lexenv)))
Expand All @@ -749,7 +749,8 @@
;;; this didn't seem to expand into an assertion, at least for ALIEN
;;; values. Check that SBCL doesn't have this problem.
(def-ir1-translator the ((type value) start cont)
(let ((*lexenv* (ir1ize-the-or-values type cont *lexenv* 'the)))
(with-continuation-type-assertion (cont (values-specifier-type type)
"in THE declaration")
(ir1-convert start cont value)))

;;; This is like the THE special form, except that it believes
Expand Down Expand Up @@ -1011,7 +1012,10 @@
(continuation-starts-block dummy-start)
(ir1-convert start dummy-start result)

(substitute-continuation-uses cont dummy-start)
(with-continuation-type-assertion
(cont (continuation-asserted-type dummy-start)
"of the first form")
(substitute-continuation-uses cont dummy-start))

(continuation-starts-block dummy-result)
(ir1-convert-progn-body dummy-start dummy-result forms)
Expand Down
34 changes: 18 additions & 16 deletions src/compiler/ir1tran.lisp
Expand Up @@ -544,21 +544,23 @@
;;; functional instead.
(defun reference-leaf (start cont leaf)
(declare (type continuation start cont) (type leaf leaf))
(let* ((leaf (or (and (defined-fun-p leaf)
(not (eq (defined-fun-inlinep leaf)
:notinline))
(let ((functional (defined-fun-functional leaf)))
(when (and functional
(not (functional-kind functional)))
(maybe-reanalyze-functional functional))))
leaf))
(res (make-ref (or (lexenv-find leaf type-restrictions)
(leaf-type leaf))
leaf)))
(push res (leaf-refs leaf))
(setf (leaf-ever-used leaf) t)
(link-node-to-previous-continuation res start)
(use-continuation res cont)))
(with-continuation-type-assertion
(cont (or (lexenv-find leaf type-restrictions) *wild-type*)
"in DECLARE")
(let* ((leaf (or (and (defined-fun-p leaf)
(not (eq (defined-fun-inlinep leaf)
:notinline))
(let ((functional (defined-fun-functional leaf)))
(when (and functional
(not (functional-kind functional)))
(maybe-reanalyze-functional functional))))
leaf))
(res (make-ref (leaf-type leaf)
leaf)))
(push res (leaf-refs leaf))
(setf (leaf-ever-used leaf) t)
(link-node-to-previous-continuation res start)
(use-continuation res cont))))

;;; Convert a reference to a symbolic constant or variable. If the
;;; symbol is entered in the LEXENV-VARS we use that definition,
Expand Down Expand Up @@ -1115,7 +1117,7 @@
`(values ,@types))
cont
res
'values))))
"in VALUES declaration"))))
(dynamic-extent
(when (policy *lexenv* (> speed inhibit-warnings))
(compiler-note
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/macros.lisp
Expand Up @@ -709,6 +709,11 @@
`(if ,n-res
(values (cdr ,n-res) t)
(values nil nil))))

;;;
(defmacro with-continuation-type-assertion ((cont ctype context) &body body)
`(let ((*lexenv* (ir1ize-the-or-values ,ctype ,cont *lexenv* ,context)))
,@body))

;;;; the EVENT statistics/trace utility

Expand Down
36 changes: 34 additions & 2 deletions tests/compiler.impure.lisp
Expand Up @@ -269,16 +269,48 @@
;; Uncomment and it works
))
(eff)))

;;; bug 192a, fixed by APD "more strict type checking" patch
;;; (sbcl-devel 2002-08-07)
(defun bug192a (x)
(declare (optimize (speed 0) (safety 3)))
;; Even with bug 192a, this declaration was checked as an assertion.
(declare (real x))
(+ x
(locally
;; Because of bug 192a, this declaration was trusted without checking.
(declare (single-float x))
(sin x))))
(assert (null (ignore-errors (bug192a nil))))
(multiple-value-bind (result error) (ignore-errors (bug192a 100))
(assert (null result))
(assert (equal (type-error-expected-type error) 'single-float)))

;;; 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))))

;;; 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)))
(assert failure-p)
(assert (raises-error? (funcall function) program-error)))

(multiple-value-bind (function warnings-p failure-p)
(compile nil '(lambda () (symbol-macrolet ((*standard-input* nil)) *standard-input*)))
(compile nil
'(lambda ()
(symbol-macrolet ((*standard-input* nil))
*standard-input*)))
(assert failure-p)
(assert (raises-error? (funcall function) program-error)))
#||
Expand Down
2 changes: 1 addition & 1 deletion tests/dump.impure-cload.lisp
Expand Up @@ -28,7 +28,7 @@
(declare (type list keys))
(loop
for c in '#1=("Red" "Blue" . #1#)
for key in keys ))
for key in keys))

;;; sbcl-0.6.11.25 or so had DEF!STRUCT/MAKE-LOAD-FORM/HOST screwed up
;;; so that the compiler couldn't dump pathnames.
Expand Down
2 changes: 1 addition & 1 deletion version.lisp-expr
Expand Up @@ -18,4 +18,4 @@
;;; for internal versions, especially for internal versions off the
;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)

"0.7.7.18"
"0.7.7.19"

0 comments on commit fb91e19

Please sign in to comment.