From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#56256: Emacs 28.1 gets stuck when typing some C++ code Date: Tue, 28 Jun 2022 16:28:27 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="30611"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Lars Ingebrigtsen , 56256@debbugs.gnu.org To: Iru Cai Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Jun 28 18:30:04 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o6E6G-0007lC-EG for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 28 Jun 2022 18:30:04 +0200 Original-Received: from localhost ([::1]:55980 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o6E6E-0007N3-Kq for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 28 Jun 2022 12:30:02 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:41504) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o6E5G-0006Cx-El for bug-gnu-emacs@gnu.org; Tue, 28 Jun 2022 12:29:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:34071) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o6E5G-0000Er-6P for bug-gnu-emacs@gnu.org; Tue, 28 Jun 2022 12:29:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1o6E5F-000373-UW for bug-gnu-emacs@gnu.org; Tue, 28 Jun 2022 12:29:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 28 Jun 2022 16:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 56256 X-GNU-PR-Package: emacs Original-Received: via spool by 56256-submit@debbugs.gnu.org id=B56256.165643372011938 (code B ref 56256); Tue, 28 Jun 2022 16:29:01 +0000 Original-Received: (at 56256) by debbugs.gnu.org; 28 Jun 2022 16:28:40 +0000 Original-Received: from localhost ([127.0.0.1]:56201 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o6E4t-00036T-Sd for submit@debbugs.gnu.org; Tue, 28 Jun 2022 12:28:40 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:61288 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1o6E4p-00036B-2U for 56256@debbugs.gnu.org; Tue, 28 Jun 2022 12:28:39 -0400 Original-Received: (qmail 71623 invoked by uid 3782); 28 Jun 2022 16:28:28 -0000 Original-Received: from acm.muc.de (p4fe1595e.dip0.t-ipconnect.de [79.225.89.94]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Tue, 28 Jun 2022 18:28:27 +0200 Original-Received: (qmail 7420 invoked by uid 1000); 28 Jun 2022 16:28:27 -0000 Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:235560 Archived-At: Hello, Iru. Thanks for taking the trouble to report this bug, and thanks even more for such a concise and helpful report. On Mon, Jun 27, 2022 at 18:22:15 +0800, Iru Cai wrote: > Emacs gets stuck when trying to type the '&' character at the end of the > buffer when there's the following code in C++ mode (this code is from > https://www.gingerbill.org/article/2015/08/19/defer-in-cpp/): > ``` > template > struct privDefer { >     F f; >     privDefer(F f) : f(f) {} >     ~privDefer() { f(); } > }; > template > privDefer defer_func(F f) { >     return privDefer(f); > } > #define DEFER_1(x, y) x##y > #define DEFER_2(x, y) DEFER_1(x, y) > #define DEFER_3(x)    DEFER_2(x, __COUNTER__) > #define defer(code) auto DEFER_3(_defer_) = defer_func([ > ``` > Steps to reproduce: > 1. create a C++ source file with this code and open it with Emacs, if > the file doesn't have a C++ source suffix, enable c++mode > 2. type the '&' symbol at the last line after "defer_func([" > 3. then Emacs gets stuck > I can see this bug in Emacs 28.1 and git revision > 5b1bb1af030597aab7f7895b6e3da9b430f9438a. I've also tried ``emacs -Q`` > and ``emacs -Q -nw``, the bug still exists. Yes. What is triggering the bug is the newly typed & being at the end of a #define line. The CC Mode function c-font-lock-c++-lambda-captures is in a loop, handling one lambda capture at a time. At the end of the file, it has just gone forward over the whitespace, and wants to return to the &. However it wrongly uses the function c-backward-token-2, which treats all the macro lines as whitespace, hence ends up at the }, 6 lines earlier. It then searches forward for the "next" [, and ends up at the same one it was at before. This loops infinitely. I think the following patch should fix it. Could you try it out on your real C++ code, please, and tell us whether the bug is actually fixed. (If you want any help with applying the patch or byte compiling CC Mode afterwards, feel free to send me private email.): diff -r 03c932b2922b cc-fonts.el --- a/cc-fonts.el Sat Jun 18 15:40:47 2022 +0000 +++ b/cc-fonts.el Tue Jun 28 16:15:37 2022 +0000 @@ -1823,7 +1823,7 @@ ;; font-lock-keyword-face. It always returns NIL to inhibit this and ;; prevent a repeat invocation. See elisp/lispref page "Search-based ;; Fontification". - (let (mode capture-default id-start id-end declaration sub-begin sub-end) + (let (mode capture-default id-start id-end declaration sub-begin sub-end tem) (while (and (< (point) limit) (search-forward "[" limit t)) (when (progn (backward-char) @@ -1835,15 +1835,18 @@ (char-after))) ;; Is the first element of the list a bare "=" or "&"? (when mode - (forward-char) - (c-forward-syntactic-ws) - (if (memq (char-after) '(?, ?\])) - (progn - (setq capture-default mode) - (when (eq (char-after) ?,) - (forward-char) - (c-forward-syntactic-ws))) - (c-backward-token-2))) + (setq tem nil) + (save-excursion + (forward-char) + (c-forward-syntactic-ws) + (if (memq (char-after) '(?, ?\])) + (progn + (setq capture-default mode) + (when (eq (char-after) ?,) + (forward-char) + (c-forward-syntactic-ws)) + (setq tem (point))))) + (if tem (goto-char tem))) ;; Go round the following loop once per captured item. We use "\\s)" ;; rather than "\\]" here to avoid infinite looping in this situation: -- Alan Mackenzie (Nuremberg, Germany).