all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Iru Cai <vimacs@disroot.org>
Cc: Lars Ingebrigtsen <larsi@gnus.org>, 56256@debbugs.gnu.org
Subject: bug#56256: Emacs 28.1 gets stuck when typing some C++ code
Date: Tue, 28 Jun 2022 16:28:27 +0000	[thread overview]
Message-ID: <YrssK5a1vujVR1v9@ACM> (raw)
In-Reply-To: <c3dc99f1-4b36-5103-7b10-2074b862aed9@disroot.org>

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 <typename F>
> struct privDefer {
>      F f;
>      privDefer(F f) : f(f) {}
>      ~privDefer() { f(); }
> };

> template <typename F>
> privDefer<F> defer_func(F f) {
>      return privDefer<F>(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).





  parent reply	other threads:[~2022-06-28 16:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-27 10:22 bug#56256: Emacs 28.1 gets stuck when typing some C++ code Iru Cai via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-28 12:52 ` Lars Ingebrigtsen
2022-06-28 16:28 ` Alan Mackenzie [this message]
2022-06-29  3:03   ` Iru Cai via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 16:23     ` Alan Mackenzie

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YrssK5a1vujVR1v9@ACM \
    --to=acm@muc.de \
    --cc=56256@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    --cc=vimacs@disroot.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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.