Subject: bug#46951: CC Mode 5.35.1 (C++/l); c-state-cache inconsistency

From: Alan Mackenzie <[email-masked]>
Date: Sat, 6 Mar 2021 14:54:20 +0000

Hello, Michael.

On Fri, Mar 05, 2021 at 16:15:20 -0500, Michael Welsh Duggan wrote:
> Package: cc-mode

> I run cc-mode with c parse state debugging turned on.  In the course of
> normal usage, I found a file that reliably triggers a cache state
> inconsistency.  (This is a courtesy report.  I'm not actually
> encountering any bad cc-mode behavior right now.)

> Reproducer:

> emacs -Q
> C-x C-f test.h RET
> M-x c-toggle-parse-state-cache RET
> M-x what-line
> C-v
> M-x what-line

> The resulting log in *Messages*:

> c-debug-parse-state enabled
> Line 1
> c-parse-state inconsistency at 2465: using cache: (2462 (1208 . 1674)), from scratch: (2462 (1863 . 2060)).  POINT-MIN: 1
> Old state:
> (setq c-state-cache '(2233 2219 2150 (1863 . 2060))  c-state-cache-good-pos 2151  c-state-nonlit-pos-cache nil  c-state-nonlit-pos-cache-limit 1  c-state-brace-pair-desert '(1 . 1208)  c-state-point-min 1  c-state-point-min-lit-type nil  c-state-point-min-lit-start nil  c-state-min-scan-pos 1  c-state-old-cpp-beg (copy-marker 1769)  c-state-old-cpp-end (copy-marker 2432)  c-parse-state-point 2244)
> c-parse-state inconsistency at 2524: using cache: (2509 (1208 . 1674)), from scratch: (2509 (1863 . 2060)).  POINT-MIN: 1
> Old state:
> (setq c-state-cache '(2462 (1208 . 1674))  c-state-cache-good-pos 2433  c-state-nonlit-pos-cache nil  c-state-nonlit-pos-cache-limit 1  c-state-brace-pair-desert '(1 . 1208)  c-state-point-min 1  c-state-point-min-lit-type nil  c-state-point-min-lit-start nil  c-state-min-scan-pos 1  c-state-old-cpp-beg (copy-marker 2434)  c-state-old-cpp-end (copy-marker 2482)  c-parse-state-point 2465)
> c-parse-state inconsistency at 2600: using cache: (2592 (1208 . 1674)), from scratch: (2592 (1863 . 2060)).  POINT-MIN: 1
> Old state:
> (setq c-state-cache '(2509 (1208 . 1674))  c-state-cache-good-pos 2483  c-state-nonlit-pos-cache nil  c-state-nonlit-pos-cache-limit 1  c-state-brace-pair-desert '(1 . 1208)  c-state-point-min 1  c-state-point-min-lit-type nil  c-state-point-min-lit-start nil  c-state-min-scan-pos 1  c-state-old-cpp-beg (copy-marker 2483)  c-state-old-cpp-end (copy-marker 2541)  c-parse-state-point 2524)
> c-parse-state inconsistency at 2610: using cache: (2592 (1208 . 1674)), from scratch: (2592 (1863 . 2060)).  POINT-MIN: 1
> Old state:
> (setq c-state-cache '(2592 (1208 . 1674))  c-state-cache-good-pos 2566  c-state-nonlit-pos-cache nil  c-state-nonlit-pos-cache-limit 1  c-state-brace-pair-desert '(1 . 1208)  c-state-point-min 1  c-state-point-min-lit-type nil  c-state-point-min-lit-start nil  c-state-min-scan-pos 1  c-state-old-cpp-beg (copy-marker 2543)  c-state-old-cpp-end (copy-marker 2634)  c-parse-state-point 2600)
> Line 32

Indeed, yes.  Thanks for the report.

The following patch (which applies cleanly to the Emacs master branch)
should fix the bug.  I will be applying it to the master branch this
afternoon.  Please feel free to test it, but if I don't hear from you,
I'll assume the bug can be closed.

Thanks again!

diff -r d6f1f920c51c cc-engine.el
--- a/cc-engine.el	Wed Mar 03 11:44:18 2021 +0000
+++ b/cc-engine.el	Sat Mar 06 14:50:58 2021 +0000
@@ -3801,12 +3801,14 @@
 		     (point)))
 	     (bra			; Position of "{".
 	      ;; Don't start scanning in the middle of a CPP construct unless
-	      ;; it contains HERE - these constructs, in Emacs, are "commented
-	      ;; out" with category properties.
-	      (if (eq (c-get-char-property macro-start-or-from 'category)
-			'c-cpp-delimiter)
-		    macro-start-or-from
-		  from))
+	      ;; it contains HERE.
+	      (if (and (not (eq macro-start-or-from from))
+		       (< macro-start-or-from here) ; Might not be needed.
+		       (progn (goto-char macro-start-or-from)
+			      (c-end-of-macro)
+			      (>= (point) here)))
+		  from
+		macro-start-or-from))
 	     ce)			; Position of "}"
 	(or upper-lim (setq upper-lim from))

[ .... ]

> -- 
> Michael Welsh Duggan
> ([email-masked])

-- 
Alan Mackenzie (Nuremberg, Germany).