emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 1440dbe: Fix an infinite loop in C++ Mode redisplay. This was bug


From: Alan Mackenzie
Subject: master 1440dbe: Fix an infinite loop in C++ Mode redisplay. This was bug #47191.
Date: Mon, 29 Mar 2021 11:36:37 -0400 (EDT)

branch: master
commit 1440dbed544a76ee3b876cb573b5110211e798bb
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>

    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.
---
 lisp/progmodes/cc-defs.el   | 20 ++++++++++++--------
 lisp/progmodes/cc-engine.el | 39 ++++++++++++++++++++++++---------------
 2 files changed, 36 insertions(+), 23 deletions(-)

diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 38fe23b..536e676 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -691,14 +691,16 @@ whitespace.
 
 LIMIT sets an upper limit of the forward movement, if specified.  If
 LIMIT or the end of the buffer is reached inside a comment or
-preprocessor directive, the point will be left there.
+preprocessor directive, the point will be left there.  If point starts
+on the wrong side of LIMIT, it stays unchanged.
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
   (if limit
-      `(save-restriction
-        (narrow-to-region (point-min) (or ,limit (point-max)))
-        (c-forward-sws))
+      `(when (< (point) (or ,limit (point-max)))
+        (save-restriction
+          (narrow-to-region (point-min) (or ,limit (point-max)))
+          (c-forward-sws)))
     '(c-forward-sws)))
 
 (defmacro c-backward-syntactic-ws (&optional limit)
@@ -710,14 +712,16 @@ whitespace.
 
 LIMIT sets a lower limit of the backward movement, if specified.  If
 LIMIT is reached inside a line comment or preprocessor directive then
-the point is moved into it past the whitespace at the end.
+the point is moved into it past the whitespace at the end.  If point
+starts on the wrong side of LIMIT, it stays unchanged.
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
   (if limit
-      `(save-restriction
-        (narrow-to-region (or ,limit (point-min)) (point-max))
-        (c-backward-sws))
+      `(when (> (point) (or ,limit (point-min)))
+        (save-restriction
+          (narrow-to-region (or ,limit (point-min)) (point-max))
+          (c-backward-sws)))
     '(c-backward-sws)))
 
 (defmacro c-forward-sexp (&optional count)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b7ad02c..cc9833a 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) ?\()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]