From: Christophe Rhodes Date: Wed, 21 Aug 2002 10:30:03 +0000 (+0000) Subject: 0.7.6.29: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=4dbc52ee4f9a4f566701f1d33e7916e8491b918b;p=sbcl.git 0.7.6.29: Fix BUGS 123 and 165, somewhat along the lines of CSR sbcl-devel 2002-08-20 "(VECTOR UNDEFTYPE)", except also catch the erroneous test in ARRAY-TYPES-INTERSECT. --- diff --git a/BUGS b/BUGS index 6fd716f..0811c12 100644 --- a/BUGS +++ b/BUGS @@ -1,4 +1,4 @@ -REPORTING BUGS +tREPORTING BUGS Bugs can be reported on the help mailing list sbcl-help@lists.sourceforge.net @@ -698,18 +698,6 @@ WORKAROUND: #+NIL) and I'd like to go back to see whether this really is a compiler bug before I delete this BUGS entry. -123: - The *USE-IMPLEMENTATION-TYPES* hack causes bugs, particularly - (IN-PACKAGE :SB-KERNEL) - (TYPE= (SPECIFIER-TYPE '(VECTOR T)) - (SPECIFIER-TYPE '(VECTOR UNDEFTYPE))) - Then because of this, the compiler bogusly optimizes - (TYPEP #(11) '(SIMPLE-ARRAY UNDEF-TYPE 1)) - to T. Unfortunately, just setting *USE-IMPLEMENTATION-TYPES* to - NIL around sbcl-0.pre7.14.flaky4.12 didn't work: the compiler complained - about type mismatches (probably harmlessly, another instance of bug 117); - and then cold init died with a segmentation fault. - 124: As of version 0.pre7.14, SBCL's implementation of MACROLET makes the entire lexical environment at the point of MACROLET available @@ -1031,27 +1019,6 @@ WORKAROUND: isn't too surprising since there are many differences in stack implementation and GC conservatism between the X86 and other ports.) -165: - Array types with element-types of some unknown type are falsely being - assumed to be of type (ARRAY T) by the compiler in some cases. The - following code demonstrates the problem: - - (defun foo (x) - (declare (type (vector bar) x)) - (aref x 1)) - (deftype bar () 'single-float) - (foo (make-array 3 :element-type 'bar)) - -> TYPE-ERROR "The value #(0.0 0.0 0.0) is not of type (VECTOR BAR)." - (typep (make-array 3 :element-type 'bar) '(vector bar)) - -> T - - The easy solution is to make the functions which depend on knowing - the upgraded-array-element-type (in compiler/array-tran and - compiler/generic/vm-tran as of sbcl-0.7.3.x) be slightly smarter about - unknown types; an alternative is to have the - specialized-element-type slot in the ARRAY-TYPE structure be - *WILD-TYPE* for UNKNOWN-TYPE element types. - 166: Compiling (in-package :cl-user) diff --git a/NEWS b/NEWS index 66875b9..5f3dca3 100644 --- a/NEWS +++ b/NEWS @@ -1194,7 +1194,10 @@ changes in sbcl-0.7.7 relative to sbcl-0.7.6: * An alpha-quality port to the parisc architecture running Linux, based on the old CMUCL backend has been made. This, even more so than the other backends, should be considered still a work in - progress. + progress; known problems include that the Linux kernel in 64-bit + mode does not propagate the correct sigcontext structure to + userspace, and consequently SBCL on a parisc64 kernel will not + work yet. * fixed bug 189: The compiler now respects NOTINLINE declarations for functions declared in FLET and LABELS. (I.e. "LET conversion" is suppressed.) Also now that the compiler is looking at declarations @@ -1234,6 +1237,8 @@ changes in sbcl-0.7.7 relative to sbcl-0.7.6: * Bug 192 fixed: The internal primitive DATA-VECTOR-REF can now be constant-folded without failing an assertion. (thanks to Einar Floystad Dorum for reporting this) + * Bugs 123 and 165 fixed: array specializations on as-yet-undefined + types are now dealt with more correctly by the compiler. * Minor incompatible change: COMPILE-FILE-PATHNAME now merges its OUTPUT-FILE argument with its INPUT-FILE argument, resulting in behaviour analogous to RENAME-FILE. This puts its behaviour more diff --git a/src/code/late-type.lisp b/src/code/late-type.lisp index 63cc7c6..8a4e03b 100644 --- a/src/code/late-type.lisp +++ b/src/code/late-type.lisp @@ -1816,13 +1816,23 @@ (array-type-element-type type))) (!define-type-method (array :simple-=) (type1 type2) - (values (and (equal (array-type-dimensions type1) - (array-type-dimensions type2)) - (eq (array-type-complexp type1) - (array-type-complexp type2)) - (type= (specialized-element-type-maybe type1) - (specialized-element-type-maybe type2))) - t)) + (if (or (unknown-type-p (array-type-element-type type1)) + (unknown-type-p (array-type-element-type type2))) + (multiple-value-bind (equalp certainp) + (type= (array-type-element-type type1) + (array-type-element-type type2)) + ;; by its nature, the call to TYPE= should never return NIL, + ;; T, as we don't know what the UNKNOWN-TYPE will grow up to + ;; be. -- CSR, 2002-08-19 + (aver (not (and (not equalp) certainp))) + (values equalp certainp)) + (values (and (equal (array-type-dimensions type1) + (array-type-dimensions type2)) + (eq (array-type-complexp type1) + (array-type-complexp type2)) + (type= (specialized-element-type-maybe type1) + (specialized-element-type-maybe type2))) + t))) (!define-type-method (array :unparse) (type) (let ((dims (array-type-dimensions type)) @@ -1928,10 +1938,28 @@ (eq complexp2 :maybe) (eq complexp1 complexp2))) (values nil t)) - ;; If either element type is wild, then they intersect. - ;; Otherwise, the types must be identical. - ((or (eq (array-type-element-type type1) *wild-type*) - (eq (array-type-element-type type2) *wild-type*) + ;; Old comment: + ;; + ;; If either element type is wild, then they intersect. + ;; Otherwise, the types must be identical. + ;; + ;; FIXME: There seems to have been a fair amount of + ;; confusion about the distinction between requested element + ;; type and specialized element type; here is one of + ;; them. If we request an array to hold objects of an + ;; unknown type, we can do no better than represent that + ;; type as an array specialized on wild-type. We keep the + ;; requested element-type in the -ELEMENT-TYPE slot, and + ;; *WILD-TYPE* in the -SPECIALIZED-ELEMENT-TYPE. So, here, + ;; we must test for the SPECIALIZED slot being *WILD-TYPE*, + ;; not just the ELEMENT-TYPE slot. Maybe the return value + ;; in that specific case should be T, NIL? Or maybe this + ;; function should really be called + ;; ARRAY-TYPES-COULD-POSSIBLY-INTERSECT? In any case, this + ;; was responsible for bug #123, and this whole issue could + ;; do with a rethink and/or a rewrite. -- CSR, 2002-08-21 + ((or (eq (array-type-specialized-element-type type1) *wild-type*) + (eq (array-type-specialized-element-type type2) *wild-type*) (type= (specialized-element-type-maybe type1) (specialized-element-type-maybe type2))) diff --git a/src/compiler/array-tran.lisp b/src/compiler/array-tran.lisp index d2eafd1..6d9a690 100644 --- a/src/compiler/array-tran.lisp +++ b/src/compiler/array-tran.lisp @@ -35,7 +35,11 @@ ;; array type. (if (array-type-p type) (array-type-specialized-element-type type) - *universal-type*))) + ;; KLUDGE: there is no good answer here, but at least + ;; *wild-type* won't cause HAIRY-DATA-VECTOR-{REF,SET} to be + ;; erroneously optimized (see generic/vm-tran.lisp) -- CSR, + ;; 2002-08-21 + *wild-type*))) ;;; The ``new-value'' for array setters must fit in the array, and the ;;; return type is going to be the same as the new-value for SETF diff --git a/src/compiler/generic/vm-type.lisp b/src/compiler/generic/vm-type.lisp index 2e0621c..279ec9d 100644 --- a/src/compiler/generic/vm-type.lisp +++ b/src/compiler/generic/vm-type.lisp @@ -130,7 +130,12 @@ (defun specialize-array-type (type) (let ((eltype (array-type-element-type type))) (setf (array-type-specialized-element-type type) - (if (eq eltype *wild-type*) + (if (or (eq eltype *wild-type*) + ;; This is slightly dubious, but not as dubious as + ;; assuming that the upgraded-element-type should be + ;; equal to T, given the way that the AREF + ;; DERIVE-TYPE optimizer works. -- CSR, 2002-08-19 + (unknown-type-p eltype)) *wild-type* (dolist (stype-name *specialized-array-element-types* *universal-type*) diff --git a/tests/type.impure.lisp b/tests/type.impure.lisp index 8b9a67c..13ee083 100644 --- a/tests/type.impure.lisp +++ b/tests/type.impure.lisp @@ -80,14 +80,10 @@ ;;; part I: TYPEP (assert (typep #(11) '(simple-array t 1))) (assert (typep #(11) '(simple-array (or integer symbol) 1))) -;;; FIXME: This is broken because of compiler bug 123: the compiler -;;; optimizes the type test to T, so it never gets a chance to raise a -;;; runtime error. (It used to work under the IR1 interpreter just -;;; because the IR1 interpreter doesn't try to optimize TYPEP as hard -;;; as the byte compiler does.) -#+nil (assert (raises-error? (typep #(11) '(simple-array undef-type 1)))) +(assert (raises-error? (typep #(11) '(simple-array undef-type 1)))) (assert (not (typep 11 '(simple-array undef-type 1)))) ;;; part II: SUBTYPEP + (assert (subtypep '(vector some-undef-type) 'vector)) (assert (not (subtypep '(vector some-undef-type) 'integer))) (assert-nil-nil (subtypep 'utype-1 'utype-2)) @@ -352,5 +348,15 @@ (assert-nil-t (subtypep 'maybe-subclass 'superclass)) ||# +;;; Prior to sbcl-0.7.6.27, there was some confusion in ARRAY types +;;; specialized on some as-yet-undefined type which would cause this +;;; program to fail (bugs #123 and #165). Verify that it doesn't. +(defun foo (x) + (declare (type (vector bar) x)) + (aref x 1)) +(deftype bar () 'single-float) +(assert (eql (foo (make-array 3 :element-type 'bar :initial-element 0.0f0)) + 0.0f0)) + ;;; success (quit :unix-status 104) diff --git a/version.lisp-expr b/version.lisp-expr index 626bd8b..2e4d022 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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.6.28" +"0.7.6.29"