1.0.13.11: ensure that sb-cover records don't clash with constants in user code
authorJuho Snellman <jsnell@iki.fi>
Wed, 2 Jan 2008 23:07:15 +0000 (23:07 +0000)
committerJuho Snellman <jsnell@iki.fi>
Wed, 2 Jan 2008 23:07:15 +0000 (23:07 +0000)
        * If a code coverage instrumentation record is coalesced with another
          constant in the same file, the "we know what we're doing" comment
          in INSTRUMENT-COVERAGE about modifying constants no longer applies.
          Changes to the record will be reflected in the other constant too,
          which is probably not what the user expected.
        * Ensure that coalescing cannot happen by using a symbol internal to
          SB-C as the CDR of the record (instead of NIL).
        * Reported separately by Christophe Rhodes and Rahul Jain.

contrib/sb-cover/cover.lisp
contrib/sb-cover/test-data-3.lisp [new file with mode: 0644]
contrib/sb-cover/tests.lisp
src/compiler/ir1tran.lisp
version.lisp-expr

index 8a38551..d697492 100644 (file)
@@ -390,9 +390,9 @@ table.summary tr.subheading td { text-align: left; font-weight: bold; padding-le
            unless (member (caar record) '(:then :else))
            collect (list mode
                          (car record)
-                         (ecase (cdr record)
-                           ((t) 1)
-                           ((nil) 2)))))
+                         (if (sb-c::code-coverage-record-marked record)
+                             1
+                             2))))
     (:branch
      (let ((hash (make-hash-table :test 'equal)))
        (dolist (record records)
@@ -400,7 +400,7 @@ table.summary tr.subheading td { text-align: left; font-weight: bold; padding-le
            (when (member (car path) '(:then :else))
              (setf (gethash (cdr path) hash)
                    (logior (gethash (cdr path) hash 0)
-                           (ash (if (cdr record)
+                           (ash (if (sb-c::code-coverage-record-marked record)
                                     1
                                     2)
                                 (if (eql (car path) :then)
diff --git a/contrib/sb-cover/test-data-3.lisp b/contrib/sb-cover/test-data-3.lisp
new file mode 100644 (file)
index 0000000..3b2a515
--- /dev/null
@@ -0,0 +1,8 @@
+(declaim (optimize sb-c::store-coverage-data))
+
+(defun test-1 ()
+  (print '((1 3 1))))
+
+(defun test-2 ()
+  (assert (equal (test-1)
+                 (list (list 1 3 1)))))
index 6fb3d9a..7903b80 100644 (file)
@@ -92,3 +92,9 @@
 ;; Complete branch coverage
 (assert (= (sb-cover::ok-of (getf sb-cover::*counts* :branch))
            (sb-cover::all-of (getf sb-cover::*counts* :branch))))
+
+;; Check for presence of constant coalescing bugs
+
+(load (compile-file (merge-pathnames #p"test-data-3.lisp" *path*)))
+(test-2)
+
index f19f445..2b0e386 100644 (file)
 \f
 ;;;; code coverage
 
+;;; Used as the CDR of the code coverage instrumentation records
+;;; (instead of NIL) to ensure that any well-behaving user code will
+;;; not have constants EQUAL to that record. This avoids problems with
+;;; the records getting coalesced with non-record conses, which then
+;;; get mutated when the instrumentation runs. Note that it's
+;;; important for multiple records for the same location to be
+;;; coalesced. -- JES, 2008-01-02
+(defconstant +code-coverage-unmarked+ '%code-coverage-unmarked%)
+
 ;;; Check the policy for whether we should generate code coverage
 ;;; instrumentation. If not, just return the original START
-;;; ctran. Otherwise ninsert code coverage instrumentation after
+;;; ctran. Otherwise insert code coverage instrumentation after
 ;;; START, and return the new ctran.
 (defun instrument-coverage (start mode form)
   ;; We don't actually use FORM for anything, it's just convenient to
                    ;; each instrument for the same block.
                    (or (gethash path *code-coverage-records*)
                        (setf (gethash path *code-coverage-records*)
-                             (cons path nil))))
+                             (cons path +code-coverage-unmarked+))))
                   (next (make-ctran))
                   (*allow-instrumenting* nil))
               (push (ctran-block start)
   (maphash (lambda (info cc)
              (declare (ignore info))
              (dolist (cc-entry cc)
-               (setf (cdr cc-entry) nil)))
+               (setf (cdr cc-entry) +code-coverage-unmarked+)))
            *code-coverage-info*))
 
+(defun code-coverage-record-marked (record)
+  (aver (consp record))
+  (ecase (cdr record)
+    ((#.+code-coverage-unmarked+) nil)
+    ((t) t)))
+
 \f
 ;;;; converting combinations
 
index f1d5354..8e4dd51 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.13.10"
+"1.0.13.11"