Subject: bug#7595: Infinite loop in cc-mode, or the coming of autumn

From: Daniel Colascione <[email-masked]>
Date: Sun, 06 Mar 2011 15:35:28 -0800

On 1/31/2011 3:08 PM, Chong Yidong wrote:
> Daniel Colascione<[email-masked]>  writes:
>
>> Hi Alan,
>>
>> On 12/16/10 1:39 PM, Alan Mackenzie wrote:
>>> Would you try out the following patch, please, which I hope fixes the
>>> problem.  (The line numbers will be a little different, but don't worry
>>> about that.)  Let me know how well it works!  Thanks.
>>
>> The patch seems to work well so far. I've replaced my workaround with
>> it, and I'll let you know whether I see any problems.
>
> I've committed Alan's patch to the branch, so that it will be in the
> forthcoming pretest.

The following patch repairs a defect in the original that results in an 
infinite loop in c-beginning-of-statement under the following circumstance:

1 #define some_macro value
2
3 [P]
4

Where [P] denotes the point.

=== modified file 'lisp/progmodes/cc-cmds.el'
--- lisp/progmodes/cc-cmds.el   2011-03-04 03:53:00 +0000
+++ lisp/progmodes/cc-cmds.el   2011-03-06 06:20:02 +0000
@@ -2518,6 +2518,8 @@
      (c-save-buffer-state
         ((count (or count 1))
          last ; start point for going back ONE chunk.  Updated each 
chunk movement.
+
+         ;; Beginning of current or previous macro
          (macro-fence
           (save-excursion (and (not (bobp)) (c-beginning-of-macro) 
(point))))
          res                            ; result from sub-function call
@@ -2580,19 +2582,15 @@
                 ;; Are we about to move backwards into or out of a
                 ;; preprocessor command?  If so, locate its beginning.
                 (when (eq (cdr res) 'macro-boundary)
-                 (setq macro-fence
-                       (save-excursion
-                         (if macro-fence
-                             (progn
-                               (end-of-line)
-                               (and (not (eobp))
-                                    (progn (c-skip-ws-forward)
-                                           (c-beginning-of-macro))
-                                    (progn (c-end-of-macro)
-                                           (point))))
-                           (and (not (eobp))
-                                (c-beginning-of-macro)
-                                (progn (c-end-of-macro) (point)))))))
+                  ;; c-back-over-illiterals stopped at the
+                  ;; first non-whitespace character after
+                  ;; the macro end, so the previous nonblank
+                  ;; line should be the macro.
+                  (setq macro-fence
+                        (save-excursion
+                          (c-backward-comments)
+                          (point))))
+
                 ;; Are we about to move backwards into a literal?
                 (when (memq (cdr res) '(macro-boundary literal))
                   (setq range (c-ascertain-preceding-literal)))