[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#47191: File as attachment
From: |
Alan Mackenzie |
Subject: |
bug#47191: File as attachment |
Date: |
Sat, 20 Mar 2021 20:30:54 +0000 |
Hello, Eli and Damien.
On Fri, Mar 19, 2021 at 17:28:03 +0200, Eli Zaretskii wrote:
> > From: Damien <dam@cosinux.org>
> > Date: Wed, 17 Mar 2021 07:48:39 +0000
> > Also here is the file as attachment to make sure it was not a copy/paste
> > error
> Thanks.
> Emacs infloops in redisplay when visiting this file, because
> fontification of this file infloops, and that happens on the master
> branch as well, so it has nothing to do with native-compilation
> branch. The infloop seems to be in c-forward-name, I attach the
> backtrace below.
> Alan, could you please look into this?
[ .... ]
> Lisp Backtrace:
> "c-forward-name" (0x8234a0)
> "c-forward-type" (0x823e30)
> "c-forward-decl-or-cast-1" (0x825240)
> 0x6d7e6e0 PVEC_COMPILED
> "c-find-decl-spots" (0x826d30)
> "c-font-lock-declarations" (0x8273c8)
> "font-lock-fontify-keywords-region" (0x827b40)
> "font-lock-default-fontify-region" (0x828190)
> "c-font-lock-fontify-region" (0x828808)
> "font-lock-fontify-region" (0x828dc8)
> 0x6fdbd30 PVEC_COMPILED
> "run-hook-wrapped" (0x829690)
> "jit-lock--run-functions" (0x829cc0)
> "jit-lock-fontify-now" (0x82a3e8)
> "jit-lock-function" (0x82aa68)
> "redisplay_internal (C function)" (0x0)
The trigger for the bug was a CC Mode "name" (the return type) which was
longer than 500 characters. This 500 was a search limit introduced for
performance reasons around the turn of the year. Part of the bug was
that when a forward scanning macro (c-forward-syntactic-ws) was given a
limit less than point, point was set back to that limit, causing the
loop.
The fix involves not ever moving point backwards in
c-forward-syntactic-ws, and recalculating the 500 character limit after
scanning a template construct; template expressions can easily be very
long.
Damien, would you please try out the following patch (the files are in
..../emacs/lisp/progmodes) on your real C++ source code, and either
confirm to us that the bug is fixed, or tell us what still needs fixing.
After applying the patch, please recompile _all_ of CC Mode (the files
..../emacs/progmodes/cc-*.el), since two macros have been amended. If
you want any help with the patching or byte compiling, feel free to send
me private mail. Thanks!
Here's the patch:
diff -r 11350de71bc6 cc-defs.el
--- a/cc-defs.el Sat Mar 06 15:11:24 2021 +0000
+++ b/cc-defs.el Sat Mar 20 20:08:58 2021 +0000
@@ -656,14 +656,16 @@
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)
@@ -675,14 +677,16 @@
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 -r 11350de71bc6 cc-engine.el
--- a/cc-engine.el Sat Mar 06 15:11:24 2021 +0000
+++ b/cc-engine.el Sat Mar 20 20:08:58 2021 +0000
@@ -8318,7 +8318,7 @@
;; 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
@@ -8338,6 +8338,7 @@
(lim+ (c-determine-+ve-limit 500)))
(while
(and
+ (< (point) lim+)
(looking-at c-identifier-key)
(progn
@@ -8387,23 +8388,28 @@
;; '*', '&' 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)
@@ -8449,6 +8455,9 @@
;; 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) ?\()
--
Alan Mackenzie (Nuremberg, Germany).