dynamic-extent scope too wide for nested closures
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
code:
(defun foo (&rest args)
(sb-thread:
(lambda ()
(flet ((bar () (apply #'format t args)))
(declare (dynamic-extent #'bar))
(bar)))))
The function BAR is declared dynamic-extent within the LAMBDA,
yet it ends up compiled like the following code instead:
(defun foo2 (&rest args)
(flet ((bar () (apply #'format t args)))
(declare (dynamic-extent #'bar))
(sb-
Which will usually lead to an "undefined behavior".
The problem is amplified because the dynamic-extent declaration maybe
inserted by any macro where e.g. the &body parameter representing function
usually does not need to exhibit an indefinite extent property.
Thus the user of such a macro will not know about the hidden gotchas.
Therefore we suggest that the current SBCL behavior is less then optimal
as it may lead to unexpected and difficult to trace errors.
Another example:
(defun foo (&rest args)
(lambda ()
(flet ((bar () (apply #'format t args)))
(declare (dynamic-extent #'bar))
(bar))))
(defparameter foo (foo "hello"))
(funcall foo) => random crash