summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-engine.el
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2021-03-29 15:32:40 +0000
committerAlan Mackenzie <acm@muc.de>2021-03-29 15:35:50 +0000
commit1440dbed544a76ee3b876cb573b5110211e798bb (patch)
tree10d9084334363f2024db65d2e4637a8479400227 /lisp/progmodes/cc-engine.el
parent309635af6949ca07da8f6bf8b8e25a1679f7f418 (diff)
downloademacs-1440dbed544a76ee3b876cb573b5110211e798bb.tar.gz
emacs-1440dbed544a76ee3b876cb573b5110211e798bb.tar.bz2
emacs-1440dbed544a76ee3b876cb573b5110211e798bb.zip
Fix an infinite loop in C++ Mode redisplay. This was bug #47191.
* lisp/progmodes/cc-defs.el (c-forward-syntactic-ws, c-backward-syntactic-ws): When point is on the wrong side of a supplied search limit, leave point unmoved rather than setting it to that limit. * lisp/progmodes/cc-engine.el (c-forward-name): After scanning a template argument list (which is not itself subject to a search limit) recalculate the search limit starting from the end point, since these argument lists can legitimately be long. At each of the scanning loops, check point hasn't gone past the limit.
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r--lisp/progmodes/cc-engine.el39
1 files changed, 24 insertions, 15 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b7ad02cf0cd..cc9833a434e 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -8300,7 +8300,7 @@ comment at the start of cc-engine.el for more info."
;; o - nil if no name is found;
;; o - 'template if it's an identifier ending with an angle bracket
;; arglist;
- ;; o - 'operator of it's an operator identifier;
+ ;; o - 'operator if it's an operator identifier;
;; o - t if it's some other kind of name.
;;
;; This function records identifier ranges on
@@ -8320,6 +8320,7 @@ comment at the start of cc-engine.el for more info."
(lim+ (c-determine-+ve-limit 500)))
(while
(and
+ (< (point) lim+)
(looking-at c-identifier-key)
(progn
@@ -8369,23 +8370,28 @@ comment at the start of cc-engine.el for more info."
;; '*', '&' or a name followed by ":: *",
;; where each can be followed by a sequence
;; of `c-opt-type-modifier-key'.
- (while (cond ((looking-at "[*&]")
- (goto-char (match-end 0))
- t)
- ((looking-at c-identifier-start)
- (and (c-forward-name)
- (looking-at "::")
- (progn
- (goto-char (match-end 0))
- (c-forward-syntactic-ws lim+)
- (eq (char-after) ?*))
- (progn
- (forward-char)
- t))))
+ (while
+ (and
+ (< (point) lim+)
+ (cond ((looking-at "[*&]")
+ (goto-char (match-end 0))
+ t)
+ ((looking-at c-identifier-start)
+ (and (c-forward-name)
+ (looking-at "::")
+ (progn
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws lim+)
+ (eq (char-after) ?*))
+ (progn
+ (forward-char)
+ t)))))
(while (progn
(c-forward-syntactic-ws lim+)
(setq pos (point))
- (looking-at c-opt-type-modifier-key))
+ (and
+ (<= (point) lim+)
+ (looking-at c-opt-type-modifier-key)))
(goto-char (match-end 1))))))
((looking-at c-overloadable-operators-regexp)
@@ -8431,6 +8437,9 @@ comment at the start of cc-engine.el for more info."
;; Maybe an angle bracket arglist.
(when (let (c-last-identifier-range)
(c-forward-<>-arglist nil))
+ ;; <> arglists can legitimately be very long, so recalculate
+ ;; `lim+'.
+ (setq lim+ (c-determine-+ve-limit 500))
(c-forward-syntactic-ws lim+)
(unless (eq (char-after) ?\()