~ 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