diff options
author | Philipp Stephani <phst@google.com> | 2021-03-18 12:40:08 +0100 |
---|---|---|
committer | Philipp Stephani <phst@google.com> | 2021-04-10 18:19:49 +0200 |
commit | 53dfd85a7f971875e716a55f010ee508bce89eed (patch) | |
tree | 3eb0b220ff838287f4d6cd3cd45d19794aceecf7 /lisp/emacs-lisp/edebug.el | |
parent | b72571ca49dd16be174f02ed14b460c136c9aaf2 (diff) | |
download | emacs-53dfd85a7f971875e716a55f010ee508bce89eed.tar.gz emacs-53dfd85a7f971875e716a55f010ee508bce89eed.tar.bz2 emacs-53dfd85a7f971875e716a55f010ee508bce89eed.zip |
Edebug: Disable backtracking when hitting a &define keyword.
Edebug doesn't deal well with backtracking out of definitions, see
Bug#41988. Rather than trying to support this rare situation (e.g. by
implementing a multipass parser), prevent it by adding an implicit
gate.
* lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op): Disable
backtracking when hitting a &define keyword.
* test/lisp/emacs-lisp/edebug-tests.el
(edebug-tests-duplicate-&define): New unit test.
(edebug-tests--duplicate-&define): New helper macro.
* doc/lispref/edebug.texi (Backtracking): Mention &define in the list
of constructs that disable backtracking.
* etc/NEWS: Document new behavior.
Diffstat (limited to 'lisp/emacs-lisp/edebug.el')
-rw-r--r-- | lisp/emacs-lisp/edebug.el | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index f1455ffe73b..365bc748741 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1942,14 +1942,16 @@ a sequence of elements." ;; Normally, &define is interpreted specially other places. ;; This should only be called inside of a spec list to match the remainder ;; of the current list. e.g. ("lambda" &define args def-body) - (edebug-make-form-wrapper - cursor - (edebug-before-offset cursor) - ;; Find the last offset in the list. - (let ((offsets (edebug-cursor-offsets cursor))) - (while (consp offsets) (setq offsets (cdr offsets))) - offsets) - specs)) + (prog1 (edebug-make-form-wrapper + cursor + (edebug-before-offset cursor) + ;; Find the last offset in the list. + (let ((offsets (edebug-cursor-offsets cursor))) + (while (consp offsets) (setq offsets (cdr offsets))) + offsets) + specs) + ;; Stop backtracking here (Bug#41988). + (setq edebug-gate t))) (cl-defmethod edebug--match-&-spec-op ((_ (eql &name)) cursor specs) "Compute the name for `&name SPEC FUN` spec operator. |