Avoid relying on current make-array default behavior

If an array will have elements read before written, ensure
it gets initialized explicitly; don't assume 0-fill.
This commit is contained in:
Douglas Katzman 2021-05-16 23:18:49 -04:00
parent 9e2d512899
commit cbdc8711ca
9 changed files with 61 additions and 16 deletions

View file

@ -374,8 +374,10 @@
;;; Skip for MSAN. Instead of returning 0, the intercepted malloc is configured
;;; to cause process termination by default on failure to allocate memory.
;;; Skip also for ARRAY-UBSAN which has a smaller ARRAY-TOTAL-SIZE-LIMIT
;;; and so doesn't get ENOMEM.
(with-test (:name :malloc-failure
:skipped-on :msan)
:skipped-on (or :array-ubsan :msan))
(assert (eq :enomem
(handler-case
(loop repeat 128

View file

@ -17,7 +17,8 @@
(let ((testcases '(;; Bug 126, confusion between high-level default string
;; initial element #\SPACE and low-level default array
;; element #\NULL, is gone.
(#\null (make-array 11 :element-type 'character) simple-string)
(#\null (make-array 11 :element-type 'character :initial-element #\null)
simple-string)
(#\space (make-string 11 :initial-element #\space) string)
(#\* (make-string 11 :initial-element #\*))
(#\null (make-string 11))
@ -25,10 +26,11 @@
(#\x (make-string 11 :initial-element #\x))
;; And the other tweaks made when fixing bug 126 didn't
;; mess things up too badly either.
(0 (make-array 11) simple-vector)
(0 (make-array 11 :initial-element 0) simple-vector)
(nil (make-array 11 :initial-element nil))
(12 (make-array 11 :initial-element 12))
(0 (make-array 11 :element-type '(unsigned-byte 4)) (simple-array (unsigned-byte 4) (*)))
(0 (make-array 11 :element-type '(unsigned-byte 4) :initial-element 0)
(simple-array (unsigned-byte 4) (*)))
(12 (make-array 11
:element-type '(unsigned-byte 4)
:initial-element 12)))))
@ -411,7 +413,10 @@
(test 'inline)
(test 'notinline)))
(with-test (:name (make-array :size-overflow))
(with-test (:name (make-array :size-overflow)
;; size limit is small enough that this fails by not failing
;; in the expected way
:skipped-on :array-ubsan)
;; 1-bit fixnum tags make array limits overflow the word length
;; when converted to bytes
(when (= sb-vm:n-fixnum-tag-bits 1)
@ -590,7 +595,7 @@
(checked-compile-and-assert
()
'(lambda (type)
(make-array 1 :element-type type))
(make-array 1 :element-type type :initial-element 0))
(('(or (eql -16) unsigned-byte)) #(0) :test #'equalp)))
(with-test (:name :check-bound-signed-bound-notes

View file

@ -1785,7 +1785,7 @@
(checked-compile-and-assert
()
`(lambda (type)
(make-array 4 :element-type type))
(make-array 4 :element-type type :initial-element 0))
(('(or (cons (satisfies eval)) atom)) #(0 0 0 0) :test #'equalp)))
(with-test (:name :substitute-single-use-lvar-exit-cleanups)

View file

@ -5,6 +5,34 @@
((0.1) (condition 'type-error))
((-1) (condition 'type-error))))
(defun pick-acceptable-default (specifier)
(let ((parse (sb-kernel:specifier-type specifier)))
; (format t "~&testcase: ~s~%" specifier)
(typecase parse
(sb-kernel:character-set-type #\a)
(sb-kernel:numeric-type
(cond ((eq (sb-kernel:numeric-type-class parse) 'float)
(ecase (sb-kernel:numeric-type-complexp parse)
(:real
(ecase (sb-kernel:numeric-type-format parse)
(single-float 1009f0)
(double-float pi)))
(:complex
(ecase (sb-kernel:numeric-type-format parse)
(single-float #c(101f0 -1f0))
(double-float #c(2d0 3.5d0))))))
(t
1)))
(t
(cond ((equal specifier '(or (eql 1.0d0) (eql 10.0d0))) ; KLUDGE
1.0d0)
((equal specifier '(member 1 2 10))
2)
((equal specifier '(complex (member 10.0 20.0)))
(complex 10.0 10.0))
(t
'whatever))))))
(with-test (:name :array-type-predicates)
(dolist (et (list* '(integer -1 200) '(integer -256 1)
'(integer 0 128)
@ -25,7 +53,9 @@
(map 'list 'sb-vm:saetp-specifier
sb-vm:*specialized-array-element-type-properties*)))
(when et
(let* ((v (make-array 3 :element-type et)))
(let* ((v (make-array 3 :element-type et
;; Pick an initial element because of the (ELT ,v 0)
:initial-element (pick-acceptable-default et))))
(checked-compile-and-assert ()
`(lambda ()
(list (if (typep ,v '(simple-array ,et (*)))

View file

@ -168,10 +168,17 @@
,@(loop for saetp across
sb-vm:*specialized-array-element-type-properties*
for specifier = (sb-vm:saetp-specifier saetp)
for array = (make-array (if specifier 10 0)
:element-type specifier)
for init = (cond ((member specifier '(character base-char))
'(:initial-element #\X))
((eq specifier 't) '(:initial-element :hello))
(specifier
`(:initial-element
,(sb-vm:saetp-initial-element-default saetp))))
for array = (apply 'make-array (if specifier 10 0)
:element-type specifier init)
for make-array = `(make-array ,(if specifier 10 0)
:element-type ',specifier)
:element-type ',specifier
,@init)
collect `(assert (and (equal (type-of ,array)
',(type-of array))
(equalp ,array

View file

@ -4778,7 +4778,7 @@
(checked-compile-and-assert ()
`(lambda (i)
(if (typep i '(integer -31 31))
(aref #. (make-array 63) (+ i 31))
(aref #.(make-array 63 :initial-element 0) (+ i 31))
(error "foo")))
((-31) 0)))
@ -5634,7 +5634,7 @@
(('vector #()) #() :test #'equalp)))
(with-test (:name (make-list :large)
:skipped-on (not :64-bit))
:skipped-on (or :array-ubsan (not :64-bit)))
(checked-compile `(lambda ()
(make-list (expt 2 28) :initial-element 0)))
(checked-compile `(lambda ()

View file

@ -949,7 +949,7 @@
(with-test (:name (:dx-flet-test ,n))
(test-dx-flet-test #',name ,n ,f1 ,f2 ,f3))))))
(def 0 (list :one) (list :two) (list :three))
(def 1 (make-array 128) (list 1 2 3 4 5 6 7 8) (list 'list))
(def 1 (make-array 128 :initial-element nil) (list 1 2 3 4 5 6 7 8) (list 'list))
(def 2 (list 1) (list 2 3) (list 4 5 6 7)))
;;; Test that unknown-values coming after a DX value won't mess up the

View file

@ -28,7 +28,8 @@ tmpscript=$TEST_FILESTEM.lisp-script
case "$SBCL_MACHINE_TYPE" in
X86-64)
cat > $tmpscript <<EOF
(let ((x (make-array (1- (expt 2 32)) :element-type '(unsigned-byte 8))))
(let ((x (make-array (min (1- array-total-size-limit) (1- (expt 2 32)))
:element-type '(unsigned-byte 8))))
(assert (> (sb-kernel:dynamic-usage) (length x)))
;; prevent compiler from getting too smart...
(eval x)

View file

@ -924,7 +924,7 @@ if a restart was invoked."
;;; Use array of fixnums because there're no atomic ops on array of word.
;;; This is either 58000 useful bits or 126000 bits depending on word size.
(defglobal *scoreboard* (make-array 2000))
(defglobal *scoreboard* (make-array 2000 :initial-element 0))
(defglobal *testpkg* (make-package "A-NICE-PACKAGE"))
(defun hammer-on-gentemp (package n-iter)