~ chicken-core (chicken-5) 51b192309f802a096735a89b8c55f5a80a509af4
commit 51b192309f802a096735a89b8c55f5a80a509af4 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sat Nov 27 15:38:56 2010 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sat Nov 27 15:38:56 2010 +0100 re-enabled undefd-in-tail-pos warning, detects self-tail-call diff --git a/scrutinizer.scm b/scrutinizer.scm index e07f0efd..e7c82dd9 100644 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -518,6 +518,16 @@ (and (pair? t) (eq? 'or (car t)) (any noreturn-type? (cdr t))))) + (define (self-call? node loc) + (case (node-class node) + ((##core#call) + (and (pair? loc) + (let ((op (first (node-subexpressions node)))) + (and (eq? '##core#variable (node-class op)) + (eq? (car loc) (first (node-parameters op))))))) + ((let) + (self-call? (last (node-subexpressions node)) loc)) + (else #f))) (define (walk n e loc dest tail) ; returns result specifier (let ((subs (node-subexpressions n)) (params (node-parameters n)) @@ -539,10 +549,12 @@ (r2 (walk a e loc dest tail))) ;;XXX this is too heavy, perhaps provide "style" warnings? ;;XXX this could also check for noreturn (same as undefined) - #;(when (and tail + (when (and tail (if (eq? '##core#undefined (node-class c)) - (not (eq? '##core#undefined (node-class a))) - (eq? '##core#undefined (node-class a)))) + (and (not (eq? '##core#undefined (node-class a))) + (not (self-call? a loc))) + (and (eq? '##core#undefined (node-class a)) + (not (self-call? c loc))))) (report loc (sprintf "conditional in tail-position has branch with undefined result:~%~%~a"Trap