Subject: bug#59070: CC Mode 5.35.1 (C/*l); Failure to completely fontify struct type

From: Alan Mackenzie <[email-masked]>
Date: Wed, 9 Nov 2022 12:45:34 +0000

Hello, Po.

On Sun, Nov 06, 2022 at 15:56:15 +0800, Po Lu via CC-Mode-help wrote:
> Package: cc-mode

> Start with the following text in a c-mode buffer:

> static const struct test_seat_controller_interface seat_controller_impl =
>   {
>     .destroy = DestroyTestSeatController,
>     .bind_seat = BindSeat,
>     .get_XIModifierState = GetXIModifierState,
>     .get_XIButtonState = GetXIButtonState,
>     .get_XIValuatorState = GetXIValuatorState,
>     .dispatch_XI_Enter = DispatchXIEnter,
>     .dispatch_XI_Leave = DispatchXILeave,
>     .dispatch_XI_Motion = DispatchXIMotion,
>     .dispatch_XI_ButtonPress = DispatchXIButtonPress,
>     .dispatch_XI_ButtonRelease = DispatchXIButtonRelease,
>   };

> move point to the end of the line reading ".dispatch_XI_ButtonPress =
> DispatchXIButtonRelease", and then type RET.  At that point,
> "test_seat_controller_interface" will no longer be completely fontified
> as a type.

Yes.  The position inside that identifier where the fontification
stopped was exactly 500 characters back from the start of the new line.
This made it easy to locate a 500 in the Lisp source causing it.  It
turned out to be an off-by-one error.

Would you please apply the attached patch, and confirm the bug is fixed
(or say what's still wrong).

Thanks!

> Emacs  : GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu)
>  of 2022-10-29
> Package: CC Mode 5.35.1 (C/*l)
> Buffer Style: gnu
> c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties category-properties 1-bit)

[ .... ]

-- 
Alan Mackenzie (Nuremberg, Germany).

diff -r 8e7964124ae3 cc-mode.el
--- a/cc-mode.el	Tue Nov 08 14:47:14 2022 +0000
+++ b/cc-mode.el	Wed Nov 09 12:36:35 2022 +0000
@@ -2371,6 +2371,8 @@
 	  ;; Go to a less nested declaration each time round this loop.
 	  (and
 	   (setq old-pos (point))
+	   ;; The following form tries to move to the end of the previous
+	   ;; declaration without moving outside of an enclosing {.
 	   (let (pseudo)
 	     (while
 		 (and
@@ -2385,7 +2387,9 @@
 			   (setq pseudo (c-cheap-inside-bracelist-p (c-parse-state)))))))
 	       (goto-char pseudo))
 	     t)
-	   (>= (point) bod-lim)
+	   (or (> (point) bod-lim)
+	       (eq bod-lim (point-min)))
+	   ;; Move forward to the start of the next declaration.
 	   (progn (c-forward-syntactic-ws)
 		  ;; Have we got stuck in a comment at EOB?
 		  (not (and (eobp)