From: Alan Mackenzie <acm@muc.de>
To: Chong Yidong <cyd@stupidchicken.com>
Cc: 7722@debbugs.gnu.org, Tassilo Horn <tassilo@member.fsf.org>
Subject: bug#7722: 24.0.50; Finding this C++ header file drops emacs into a infinite loop
Date: Fri, 4 Feb 2011 22:22:07 +0000 [thread overview]
Message-ID: <20110204222207.GA2424@muc.de> (raw)
In-Reply-To: <87hbd0y8sb.fsf@stupidchicken.com>
Hi there, Yidong, Tassilo,
On Sat, Jan 22, 2011 at 03:37:24PM -0500, Chong Yidong wrote:
> Tassilo Horn <tassilo@member.fsf.org> writes:
> > Originally reported by Caligo <iteronvexor@gmail.com>
> > He uses GNU Emacs 23.2.1 (x86_64-pc-linux-gnu, GTK+ Version 2.20.1),
> > but the bug in still in the current bzr trunk.
> > 1. emacs -Q bug.hpp
> > 2. emacs loops infinitely using 100% CPU resources
> > The offending file is that (according to the original reporter, the
> > spaces and empty lines are needed):
> I can reproduce this (file attached for convenience). Alan, could you
> take a look? Looks like a loop in c-forward-<>-arglist-recur:
It was indeed such a loop. It was caused by a 500n jit-lock boundary
falling in the middle of a template construct, hence the "necessity" of
all the whitespace to reproduce the failure.
Here's a putative patch for the problem. I've refactored the offending
function by replacing obscenely nested `if'-forms with a simple `cond'.
I've also removed some narrowing (to the 500n limit) which should help
jit-lock, hopefully without hurting too much elsewhere.
Tassilo, would you try out the patch, please, and let me know how it
goes. Thanks!
=== modified file 'lisp/progmodes/cc-engine.el'
*** lisp/progmodes/cc-engine.el 2011-01-31 23:54:50 +0000
--- lisp/progmodes/cc-engine.el 2011-02-04 22:12:46 +0000
***************
*** 5455,5463 ****
(goto-char start)
nil))
! (forward-char)
(unless (looking-at c-<-op-cont-regexp)
(while (and
(progn
(c-forward-syntactic-ws)
--- 5455,5465 ----
(goto-char start)
nil))
! (forward-char) ; Forward over the opening '<'.
(unless (looking-at c-<-op-cont-regexp)
+ ;; go forward one non-alphanumeric character (group) per iteration of
+ ;; this loop.
(while (and
(progn
(c-forward-syntactic-ws)
***************
*** 5486,5492 ****
(c-forward-type)
(c-forward-syntactic-ws))))))
! (setq pos (point))
;; Note: These regexps exploit the match order in \| so
;; that "<>" is matched by "<" rather than "[^>:-]>".
--- 5488,5494 ----
(c-forward-type)
(c-forward-syntactic-ws))))))
! (setq pos (point)) ; e.g. first token inside the '<'
;; Note: These regexps exploit the match order in \| so
;; that "<>" is matched by "<" rather than "[^>:-]>".
***************
*** 5522,5559 ****
;; Either an operator starting with '<' or a nested arglist.
(setq pos (point))
(let (id-start id-end subres keyword-match)
! (if (if (looking-at c-<-op-cont-regexp)
! (setq tmp (match-end 0))
! (setq tmp pos)
! (backward-char)
! (not
! (and
!
! (save-excursion
! ;; There's always an identifier before an angle
! ;; bracket arglist, or a keyword in
! ;; `c-<>-type-kwds' or `c-<>-arglist-kwds'.
! (c-backward-syntactic-ws)
! (setq id-end (point))
! (c-simple-skip-symbol-backward)
! (when (or (setq keyword-match
! (looking-at c-opt-<>-sexp-key))
! (not (looking-at c-keywords-regexp)))
! (setq id-start (point))))
!
! (setq subres
! (let ((c-promote-possible-types t)
! (c-record-found-types t))
! (c-forward-<>-arglist-recur
! (and keyword-match
! (c-keyword-member
! (c-keyword-sym (match-string 1))
! 'c-<>-type-kwds)))))
! )))
!
! ;; It was not an angle bracket arglist.
! (goto-char tmp)
!
;; It was an angle bracket arglist.
(setq c-record-found-types subres)
--- 5524,5558 ----
;; Either an operator starting with '<' or a nested arglist.
(setq pos (point))
(let (id-start id-end subres keyword-match)
! (cond
! ;; The '<' begins a multi-char operator.
! ((looking-at c-<-op-cont-regexp)
! (setq tmp (match-end 0))
! (goto-char (match-end 0)))
! ;; We're at a nested <.....>
! ((progn
! (setq tmp pos)
! (backward-char) ; to the '<'
! (and
! (save-excursion
! ;; There's always an identifier before an angle
! ;; bracket arglist, or a keyword in `c-<>-type-kwds'
! ;; or `c-<>-arglist-kwds'.
! (c-backward-syntactic-ws)
! (setq id-end (point))
! (c-simple-skip-symbol-backward)
! (when (or (setq keyword-match
! (looking-at c-opt-<>-sexp-key))
! (not (looking-at c-keywords-regexp)))
! (setq id-start (point))))
! (setq subres
! (let ((c-promote-possible-types t)
! (c-record-found-types t))
! (c-forward-<>-arglist-recur
! (and keyword-match
! (c-keyword-member
! (c-keyword-sym (match-string 1))
! 'c-<>-type-kwds)))))))
;; It was an angle bracket arglist.
(setq c-record-found-types subres)
***************
*** 5567,5574 ****
(c-forward-syntactic-ws)
(looking-at c-opt-identifier-concat-key)))
(c-record-ref-id (cons id-start id-end))
! (c-record-type-id (cons id-start id-end))))))
! t)
((and (not c-restricted-<>-arglists)
(or (and (eq (char-before) ?&)
--- 5566,5578 ----
(c-forward-syntactic-ws)
(looking-at c-opt-identifier-concat-key)))
(c-record-ref-id (cons id-start id-end))
! (c-record-type-id (cons id-start id-end)))))
!
! ;; At a "less than" operator.
! (t
! (forward-char)
! )))
! t) ; carry on looping.
((and (not c-restricted-<>-arglists)
(or (and (eq (char-before) ?&)
=== modified file 'lisp/progmodes/cc-fonts.el'
*** lisp/progmodes/cc-fonts.el 2011-01-25 04:08:28 +0000
--- lisp/progmodes/cc-fonts.el 2011-02-04 22:10:01 +0000
***************
*** 1082,1088 ****
(boundp 'parse-sexp-lookup-properties))))
;; Below we fontify a whole declaration even when it crosses the limit,
! ;; to avoid gaps when lazy-lock fontifies the file a screenful at a
;; time. That is however annoying during editing, e.g. the following is
;; a common situation while the first line is being written:
;;
--- 1082,1088 ----
(boundp 'parse-sexp-lookup-properties))))
;; Below we fontify a whole declaration even when it crosses the limit,
! ;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
;; time. That is however annoying during editing, e.g. the following is
;; a common situation while the first line is being written:
;;
***************
*** 1094,1102 ****
;; "some_other_variable" as an identifier, and the latter will not
;; correct itself until the second line is changed. To avoid that we
;; narrow to the limit if the region to fontify is a single line.
! (narrow-to-region
! (point-min)
! (if (<= limit (c-point 'bonl))
(save-excursion
;; Narrow after any operator chars following the limit though,
;; since those characters can be useful in recognizing a
--- 1094,1102 ----
;; "some_other_variable" as an identifier, and the latter will not
;; correct itself until the second line is changed. To avoid that we
;; narrow to the limit if the region to fontify is a single line.
! (if (<= limit (c-point 'bonl))
! (narrow-to-region
! (point-min)
(save-excursion
;; Narrow after any operator chars following the limit though,
;; since those characters can be useful in recognizing a
***************
*** 1104,1111 ****
;; after the header).
(goto-char limit)
(skip-chars-forward c-nonsymbol-chars)
! (point))
! limit))
(c-find-decl-spots
limit
--- 1104,1110 ----
;; after the header).
(goto-char limit)
(skip-chars-forward c-nonsymbol-chars)
! (point))))
(c-find-decl-spots
limit
--
Alan Mackenzie (Nuremberg, Germany).
next prev parent reply other threads:[~2011-02-04 22:22 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-24 8:28 bug#7722: 24.0.50; Finding this C++ header file drops emacs into a infinite loop Tassilo Horn
2011-01-22 20:37 ` Chong Yidong
2011-01-27 0:55 ` Chong Yidong
2011-01-30 21:23 ` Daniel Colascione
2011-02-04 22:22 ` Alan Mackenzie [this message]
2011-02-06 19:20 ` Tassilo Horn
2011-02-12 1:25 ` Chong Yidong
2011-02-13 12:20 ` Alan Mackenzie
2011-02-13 20:41 ` Chong Yidong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110204222207.GA2424@muc.de \
--to=acm@muc.de \
--cc=7722@debbugs.gnu.org \
--cc=cyd@stupidchicken.com \
--cc=tassilo@member.fsf.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).