~ chicken-core (chicken-5) 2e45f04a2facdd51d86cd38fb1ed12cdf2d85f26
commit 2e45f04a2facdd51d86cd38fb1ed12cdf2d85f26
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Nov 19 05:30:52 2010 -0500
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Fri Nov 19 05:30:52 2010 -0500
warn if conditional one node branch in tail-position is (##core#undefined) and one is not (suggested by Joerg Wittenberger)
diff --git a/scrutinizer.scm b/scrutinizer.scm
index a18634f7..e321032e 100644
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -518,11 +518,11 @@
(and (pair? t)
(eq? 'or (car t))
(any noreturn-type? (cdr t)))))
- (define (walk n e loc dest) ; returns result specifier
+ (define (walk n e loc dest tail) ; returns result specifier
(let ((subs (node-subexpressions n))
(params (node-parameters n))
(class (node-class n)) )
- (d "walk: ~a ~a (loc: ~a, dest: ~a)" class params loc dest)
+ (d "walk: ~a ~a (loc: ~a, dest: ~a, tail: ~a)" class params loc dest tail)
(let ((results
(case class
((quote) (list (constant-result (first params))))
@@ -530,30 +530,40 @@
((##core#proc) '(procedure))
((##core#global-ref) (global-result (first params) loc))
((##core#variable) (variable-result (first params) e loc))
- ((if) (let ((rt (single "in conditional" (walk (first subs) e loc dest) loc)))
- (always-true rt loc n)
- (let ((r1 (walk (second subs) e loc dest))
- (r2 (walk (third subs) e loc dest)))
- (cond ((and (not (eq? r1 '*))
- (not (eq? '* r2)) )
- (when (and (not (any noreturn-type? r1))
- (not (any noreturn-type? r2))
- (not (= (length r1) (length r2))))
- (report
- loc
- (sprintf
- "branches in conditional expression differ in the number of results:~%~%~a"
- (pp-fragment n))))
- (map (lambda (t1 t2) (simplify `(or ,t1 ,t2)))
- r1 r2))
- (else '*)))))
+ ((if)
+ (let ((rt (single "in conditional" (walk (first subs) e loc dest #f) loc))
+ (c (second subs))
+ (a (third subs)))
+ (always-true rt loc n)
+ (let ((r1 (walk c e loc dest tail))
+ (r2 (walk a e loc dest tail)))
+ (when (and tail
+ (if (eq? '##core#undefined (node-class c))
+ (not (eq? '##core#undefined (node-class a)))
+ (eq? '##core#undefined (node-class a))))
+ (report
+ loc
+ (sprintf "conditional in tail-position has branch with undefined result:~%~%~a"
+ (pp-fragment n))))
+ (cond ((and (not (eq? '* r1)) (not (eq? '* r2)))
+ (when (and (not (any noreturn-type? r1))
+ (not (any noreturn-type? r2))
+ (not (= (length r1) (length r2))))
+ (report
+ loc
+ (sprintf
+ "branches in conditional expression differ in the number of results:~%~%~a"
+ (pp-fragment n))))
+ (map (lambda (t1 t2) (simplify `(or ,t1 ,t2)))
+ r1 r2))
+ (else '*)))))
((let)
(let loop ((vars params) (body subs) (e2 '()))
(if (null? vars)
- (walk (car body) (append e2 e) loc dest)
+ (walk (car body) (append e2 e) loc dest tail)
(let ((t (single
(sprintf "in `let' binding of `~a'" (real-name (car vars)))
- (walk (car body) e loc (car vars)) loc)))
+ (walk (car body) e loc (car vars) #f) loc)))
(loop (cdr vars) (cdr body) (alist-cons (car vars) t e2))))))
((##core#lambda lambda)
(decompose-lambda-list
@@ -567,7 +577,7 @@
(r (walk (first subs)
(if rest (alist-cons rest 'list e2) e2)
(add-loc dest loc)
- #f)))
+ #f #t)))
(list
(append
'(procedure)
@@ -579,7 +589,7 @@
(type (##sys#get var '##core#type))
(rt (single
(sprintf "in assignment to `~a'" var)
- (walk (first subs) e loc var)
+ (walk (first subs) e loc var #f)
loc))
(b (assq var e)) )
(when (and type (not b)
@@ -604,17 +614,17 @@
"operator position"
(sprintf "argument #~a" i))
f)
- (walk n e loc #f) loc))
+ (walk n e loc #f #f) loc))
subs (iota (length subs)))))
(call-result args e loc (first subs) params)))
((##core#switch ##core#cond)
(bomb "unexpected node class: ~a" class))
(else
- (for-each (lambda (n) (walk n e loc #f)) subs)
+ (for-each (lambda (n) (walk n e loc #f #f)) subs)
'*))))
(d " -> ~a" results)
results)))
- (walk (first (node-subexpressions node)) '() '() #f))
+ (walk (first (node-subexpressions node)) '() '() #f #f))
(define (load-type-database name #!optional (path (repository-path)))
(and-let* ((dbfile (file-exists? (make-pathname path name))))
Trap