dynamic-extent scope too wide for nested closures

Bug #1761306 reported by Andrzej Walczak on 2018-04-04
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

code:

(defun foo (&rest args)
  (sb-thread:make-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-thread:make-thread #'bar)))

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

summary: - dynamic-extent scope to wide
+ dynamic-extent scope too wide for nested closures
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers