Opened 6 years ago

Closed 6 years ago

#1430 closed defect (invalid)

local binding should not trigger scrutinizer warning

Reported by: felix winkelmann Owned by:
Priority: major Milestone: 5.0
Component: scrutinizer Version: 4.13.0
Keywords: Cc: sjamaan, evhan
Estimated difficulty: hard

Description

In tests/syntax-tests.scm, the following warning is produced:

{{
" (syntax-tests.scm:412) in procedure call to chicken.base#exit', expected argument #1 of type fixnum' but was given an argument of type `false"'
}}

exit is a local variable (an exit procedure from a loop macro. Either hygiene is not properly handled here, or the scrutinizer mistakes a local binding of exit for the global one (chicken.base#exit).

Change History (4)

comment:1 Changed 6 years ago by sjamaan

I think the macro definition of while0 is in the wrong; exit is supposed to be unhygienically introduced by loop, but syntax-rules references exit hygienically.

This would originally have been the same because exit at toplevel was bound to a procedure directly, but that's more of an accident than intentional. So the macro(s?) will need to be rewritten to correctly refer to the intended exit. This probably means we need to pass the exit identifier to while0, or turn while0 into a low-level macro which refers to exit.

comment:2 Changed 6 years ago by felix winkelmann

Summary: local binding should not trigger scritinizer warninglocal binding should not trigger scrutinizer warning

comment:3 Changed 6 years ago by sjamaan

Aha! It looks like the purpose of this test is exactly to ensure that exit is the exit procedure and not the exit of the loop, which is why it is wrapped in (f ..). The code is supposed to raise an exception:

#;1> (define-syntax loop
  (er-macro-transformer
   (lambda (x r c)
     (let ((body (cdr x)))
       `(,(r 'call/cc)
         (,(r 'lambda) (exit)
          (,(r 'let) ,(r 'f) () ,@body (,(r 'f)))))))))
#;2> (define-syntax while0
  (syntax-rules ()
    ((_ t b ...)
     (loop (if (not t) (exit #f)) 
           b ...))))
#;3> (while0 #f (print "no."))

Error: bad argument type - not a fixnum: #f

        Call history:

        <syntax>          (##core#lambda () (if71 (not72 #f) (exit73 #f)) (print "no.") (f77))
        <syntax>          (##core#begin (##core#if (not72 #f) (exit73 #f)) (print "no.") (f77))
        <syntax>          (##core#if (not72 #f) (exit73 #f))
        <syntax>          (not72 #f)
        <syntax>          (exit73 #f)
        <syntax>          (##core#undefined)
        <syntax>          (print "no.")
        <syntax>          (##core#begin (f77))
        <syntax>          (f77)
        <syntax>          (##core#let () f77)
        <syntax>          (##core#begin f77)
        <syntax>          (##core#undefined)
        <eval>    (call/cc74 (lambda75 (exit) (let76 f77 () (if71 (not72 #f) (exit73 #f)) (print "no.") (f77))))
        <eval>    ((##core#letrec* ((f77 (##core#loop-lambda () (if71 (not72 #f) (exit73 #f)) (print "no.") (f77)))) f...
        <eval>    (not72 #f)
        <eval>    (exit73 #f)   <--

So the scrutinizer warning seems correct to me. If you agree, we can close this ticket.

comment:4 Changed 6 years ago by felix winkelmann

Resolution: invalid
Status: newclosed

Yep, sounds right.

Note: See TracTickets for help on using tickets.