GNU bug report logs - #72279
[PATCH] Non-local exits from outside the lexical scope are caught by cl-block

Previous Next

Package: emacs;

Reported by: Thuna <thuna.cing <at> gmail.com>

Date: Wed, 24 Jul 2024 17:37:02 UTC

Severity: normal

Tags: patch

Full log


View this message in rfc822 format

From: Thuna <thuna.cing <at> gmail.com>
To: 72279 <at> debbugs.gnu.org
Subject: bug#72279: [PATCH] Non-local exits from outside the lexical scope are caught by cl-block
Date: Wed, 24 Jul 2024 19:36:13 +0200
[Message part 1 (text/plain, inline)]
Since the thrown and caught tags in `cl-block' and `cl-return-from' are
interned and deterministic, a `cl-block' catches `cl-return-from's with
the corresponding names even from outside the current lexical scope.

The only mechanism in place to stop this is the compiler macro around
cl--block-catch, which removes the block if no approriate returns are
found, however not only is this bound to break if the compiler macro
fails to expand, a valid exit is all that is needed to work around this.

  (defun foo () (cl-return "ruh roh"))
  (cl-block nil (foo) (cl-return t)) ; => "ruh ruh"

The first patch attached attempts to solve this by moving the
functionality of the wrapper compiler macros to the macros themselves
and by using uninterned symbols for the thrown and caught tags,
communicated by the block to the corresponding returns.  All the
existing tests seemed to run just fine but I did not do any
comprehensive testing (and there doesn't appear to be any relevant
suites either).

I do take minor issue with `macroexpand-all'ing all things inside a
block, making debugging via macrostep really annoying, but I don't know
of a better solution, outside of communicating the tag during
evaluation, which would look something like the second patch.

PS. I would also like to have a discussion about a problem that I have
noticed when trying to build with the second patch, maybe here maybe in
another bug: Because struct slots are defined using `cl-defsubst', the
whole body is wrapped in a `cl-block'.  The only reason `setf' works
with such slots is because `cl-block' expands into the body itself when
there are no `cl-return's.  If it were to instead expand into a `catch'
- whether because there is a `cl-return' or because `cl-block' is
modified to always expandi into a `catch' as it is in my second patch -
the setf will expand into (setf catch) which is not defined.  I see two
possible solutions, either define a (setf catch) or switch to defsubst
instead of cl-defsubst.

[0001-Use-uninterned-tags-in-cl-block-remove-block-wrapper.patch (text/x-patch, attachment)]
[0002-Avoid-macroexpanding-in-cl-block.patch (text/x-patch, attachment)]

This bug report was last modified 161 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.