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)