Subject: bug#7930: Forgot to include the file

From: Alan Mackenzie <[email-masked]>
Date: Sun, 20 Feb 2011 15:26:16 +0000

Hi, Michael.

Here's a patch for the bug.  Would you please try it out and let me know
it's OK.

Thanks a lot for taking the trouble to pin this one down, and for
reporting it in such a high quality fashion.  It was a nasty little bug
caused by a mistaken tacit assumption in an internal CC Mode cache.

The cache in question maintains a list of "safe" positions every ~10,000
characters, and in your file position 10,001 was in the middle of a
macro.  It transpires that inside a macro is NOT a safe position ;-(.

Here's the patch (don't worry that the line numbers don't match
exactly):

*** orig/cc-engine.el	2011-02-06 15:53:22.000000000 +0000
--- cc-engine.el	2011-02-18 20:59:13.854308264 +0000
***************
*** 2026,2034 ****
  
  (defvar c-state-nonlit-pos-cache nil)
  (make-variable-buffer-local 'c-state-nonlit-pos-cache)
! ;; A list of buffer positions which are known not to be in a literal.  This is
! ;; ordered with higher positions at the front of the list.  Only those which
! ;; are less than `c-state-nonlit-pos-cache-limit' are valid.
  
  (defvar c-state-nonlit-pos-cache-limit 1)
  (make-variable-buffer-local 'c-state-nonlit-pos-cache-limit)
--- 2026,2034 ----
  
  (defvar c-state-nonlit-pos-cache nil)
  (make-variable-buffer-local 'c-state-nonlit-pos-cache)
! ;; A list of buffer positions which are known not to be in a literal or a cpp
! ;; construct.  This is ordered with higher positions at the front of the list.
! ;; Only those which are less than `c-state-nonlit-pos-cache-limit' are valid.
  
  (defvar c-state-nonlit-pos-cache-limit 1)
  (make-variable-buffer-local 'c-state-nonlit-pos-cache-limit)
***************
*** 2059,2064 ****
--- 2059,2070 ----
    ;; This function is almost the same as `c-literal-limits'.  It differs in
    ;; that it is a lower level function, and that it rigourously follows the
    ;; syntax from BOB, whereas `c-literal-limits' uses a "local" safe position.
+   ;;
+   ;; NOTE: This function manipulates `c-state-nonlit-pos-cache'.  This cache
+   ;; MAY NOT contain any positions within macros, since macros are frequently
+   ;; turned into comments by use of the `c-cpp-delimiter' category properties.
+   ;; We cannot rely on this mechanism whilst determining a cache pos since
+   ;; this function is also called from outwith `c-parse-state'.
    (save-restriction
      (widen)
      (save-excursion
***************
*** 2077,2082 ****
--- 2083,2093 ----
  		   here)
  	  (setq lit (c-state-pp-to-literal pos npos))
  	  (setq pos (or (cdr lit) npos)) ; end of literal containing npos.
+ 	  (goto-char pos)
+ 	  (when (and (c-beginning-of-macro) (/= (point) pos))
+ 	    (c-syntactic-end-of-macro)
+ 	    (or (eobp) (forward-char))
+ 	    (setq pos (point)))
  	  (setq c-state-nonlit-pos-cache (cons pos c-state-nonlit-pos-cache)))
  
  	(if (> pos c-state-nonlit-pos-cache-limit)
***************
*** 2161,2167 ****
  ;; of fruitless backward scans.
  (defvar c-state-brace-pair-desert nil)
  (make-variable-buffer-local 'c-state-brace-pair-desert)
! ;; Used only in `c-append-lower-brace-pair-to-state-cache'.  It is set when an
  ;; that defun has searched backwards for a brace pair and not found one.  Its
  ;; value is either nil or a cons (PA . FROM), where PA is the position of the
  ;; enclosing opening paren/brace/bracket which bounds the backwards search (or
--- 2172,2178 ----
  ;; of fruitless backward scans.
  (defvar c-state-brace-pair-desert nil)
  (make-variable-buffer-local 'c-state-brace-pair-desert)
! ;; Used only in `c-append-lower-brace-pair-to-state-cache'.  It is set when
  ;; that defun has searched backwards for a brace pair and not found one.  Its
  ;; value is either nil or a cons (PA . FROM), where PA is the position of the
  ;; enclosing opening paren/brace/bracket which bounds the backwards search (or
***************
*** 2846,2851 ****
--- 2857,2885 ----
  	c-state-old-cpp-end nil)
    (c-state-mark-point-min-literal))
  
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; Debugging routines to dump `c-state-cache' in a "replayable" form.
+ ;; (defmacro c-sc-de (elt) 		; "c-state-cache-dump-element"
+ ;;   `(format ,(concat "(setq " (symbol-name elt) " %s)    ") ,elt))
+ ;; (defmacro c-sc-qde (elt)		; "c-state-cache-quote-dump-element"
+ ;;   `(format ,(concat "(setq " (symbol-name elt) " '%s)    ") ,elt))
+ ;; (defun c-state-dump ()
+ ;;   ;; For debugging.
+ ;;   ;(message
+ ;;   (concat
+ ;;    (c-sc-qde c-state-cache)
+ ;;    (c-sc-de c-state-cache-good-pos)
+ ;;    (c-sc-qde c-state-nonlit-pos-cache)
+ ;;    (c-sc-de c-state-nonlit-pos-cache-limit)
+ ;;    (c-sc-qde c-state-brace-pair-desert)
+ ;;    (c-sc-de c-state-point-min)
+ ;;    (c-sc-de c-state-point-min-lit-type)
+ ;;    (c-sc-de c-state-point-min-lit-start)
+ ;;    (c-sc-de c-state-min-scan-pos)
+ ;;    (c-sc-de c-state-old-cpp-beg)
+ ;;    (c-sc-de c-state-old-cpp-end)))
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
  (defun c-invalidate-state-cache-1 (here)
    ;; Invalidate all info on `c-state-cache' that applies to the buffer at HERE
    ;; or higher and set `c-state-cache-good-pos' accordingly.  The cache is

On Thu, Jan 27, 2011 at 03:26:57PM -0500, Michael Welsh Duggan wrote:
> Included is pdusource.c:

> /*
> ** Copyright (C) 2004-2011 by Carnegie Mellon University.
> **
> ** @OPENSOURCE_HEADER_START@

[ .... ]

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

-- 
Alan Mackenzie (Nuremberg, Germany).