From 26bfd0cdcf8bdf4569608227c527bebd755ef2e6 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 7 Mar 2021 19:03:36 -0500 Subject: [PATCH] * lisp/cedet/semantic/bovine.el: Fix recent regression The conversion to `lexical-binding` introduced a regression because `bovine/c.el` relied on inspecting the local variable `lse` in one of its callers. (semantic-bovinate-stream): Bind `lse` dynamically, because of `semantic-parse-region-c-mode`. (semantic-bovinate-nonterminal-check-map): Rename from `semantic-bovinate-nonterminal-check-obarray` to hold some other kind of table. (semantic-bovinate-nonterminal-check): Use a hash-table instead of an obarray. * lisp/cedet/semantic/bovine/c.el (semantic-parse-region-c-mode): Declare use of `lse` via dynamic scoping. * test/lisp/cedet/semantic-utest-c.el (semantic-test-c-preprocessor-simulation): Re-enable test. --- lisp/cedet/semantic/bovine.el | 27 ++++++++++++++------------- lisp/cedet/semantic/bovine/c.el | 4 +++- test/lisp/cedet/semantic-utest-c.el | 3 +-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el index b585e387fed..6be6dfd8dfd 100644 --- a/lisp/cedet/semantic/bovine.el +++ b/lisp/cedet/semantic/bovine.el @@ -41,7 +41,7 @@ ;;; Variables ;; -(defvar-local semantic-bovinate-nonterminal-check-obarray nil +(defvar-local semantic-bovinate-nonterminal-check-map nil "Obarray of streams already parsed for nonterminal symbols. Use this to detect infinite recursion during a parse.") @@ -79,21 +79,18 @@ environment of `semantic-bovinate-stream'." (defun semantic-bovinate-nonterminal-check (stream nonterminal) "Check if STREAM not already parsed for NONTERMINAL. If so abort because an infinite recursive parse is suspected." - (or (vectorp semantic-bovinate-nonterminal-check-obarray) - (setq semantic-bovinate-nonterminal-check-obarray - (make-vector 13 nil))) - (let* ((nt (symbol-name nonterminal)) - (vs (symbol-value - (intern-soft - nt semantic-bovinate-nonterminal-check-obarray)))) + (or (hash-table-p semantic-bovinate-nonterminal-check-map) + (setq semantic-bovinate-nonterminal-check-map + (make-hash-table :test #'eq))) + (let* ((vs (gethash nonterminal semantic-bovinate-nonterminal-check-map))) (if (memq stream vs) ;; Always enter debugger to see the backtrace (let ((debug-on-signal t) (debug-on-error t)) - (setq semantic-bovinate-nonterminal-check-obarray nil) - (error "Infinite recursive parse suspected on %s" nt)) - (set (intern nt semantic-bovinate-nonterminal-check-obarray) - (cons stream vs))))) + (setq semantic-bovinate-nonterminal-check-map nil) + (error "Infinite recursive parse suspected on %s" nonterminal)) + (push stream + (gethash nonterminal semantic-bovinate-nonterminal-check-map))))) ;;;###autoload (defun semantic-bovinate-stream (stream &optional nonterminal) @@ -110,6 +107,9 @@ list of semantic tokens found." (or semantic--buffer-cache (semantic-bovinate-nonterminal-check stream nonterminal)) + ;; FIXME: `semantic-parse-region-c-mode' inspects `lse' to try and + ;; detect a recursive call (used with macroexpansion, to avoid inf-loops). + (with-suppressed-warnings ((lexical lse)) (defvar lse)) (let* ((table semantic--parse-table) (matchlist (cdr (assq nonterminal table))) (starting-stream stream) @@ -216,7 +216,8 @@ list of semantic tokens found." (setq cvl (cons (if (memq (semantic-lex-token-class lse) '(comment semantic-list)) - valdot val) cvl))) ;append unchecked value. + valdot val) + cvl))) ;append unchecked value. (setq end (semantic-lex-token-end lse)) ) (setq lte nil cvl nil)) ;No more matches, exit diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el index 7be55ea9e10..5712f9b6df0 100644 --- a/lisp/cedet/semantic/bovine/c.el +++ b/lisp/cedet/semantic/bovine/c.el @@ -819,7 +819,9 @@ MACRO expansion mode is handled through the nature of Emacs's non-lexical binding of variables. START, END, NONTERMINAL, DEPTH, and RETURNONERRORS are the same as for the parent." - (if (and (boundp 'lse) (or (/= start 1) (/= end (point-max)))) + ;; FIXME: We shouldn't depend on the internals of `semantic-bovinate-stream'. + (with-suppressed-warnings ((lexical lse)) (defvar lse)) + (if (and (boundp 'lse) (or (/= start (point-min)) (/= end (point-max)))) (let* ((last-lexical-token lse) (llt-class (semantic-lex-token-class last-lexical-token)) (llt-fakebits (car (cdr last-lexical-token))) diff --git a/test/lisp/cedet/semantic-utest-c.el b/test/lisp/cedet/semantic-utest-c.el index b881cdb93b3..d08c79cad3e 100644 --- a/test/lisp/cedet/semantic-utest-c.el +++ b/test/lisp/cedet/semantic-utest-c.el @@ -43,10 +43,9 @@ (defvar semantic-lex-c-nested-namespace-ignore-second) ;;; Code: -;;;###autoload (ert-deftest semantic-test-c-preprocessor-simulation () "Run parsing test for C from the test directory." - :tags '(:expensive-test :unstable) + :tags '(:expensive-test) (semantic-mode 1) (dolist (fp semantic-utest-c-comparisons) (let* ((semantic-lex-c-nested-namespace-ignore-second nil) -- 2.39.2