Subject: bug#7918: closed (Re: bug#7918: [PATCH] cc-mode: only the first clause of a for-loop should be checked for declarations)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 25 Apr 2016 18:09:02 +0000

Your bug report

#7918: [PATCH] cc-mode: only the first clause of a for-loop should be checked for declarations

which was filed against the emacs,cc-mode package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
7918: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7918
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#7918: [PATCH] cc-mode: only the first clause of a for-loop should be checked for declarations
From: Alan Mackenzie <[email-masked]>
To: [email-masked]
Cc: Lars Ingebrigtsen <[email-masked]>, Daniel Colascione <[email-masked]>
Date: Mon, 25 Apr 2016 18:04:30 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Bug fixed in master branch.

-- 
Alan Mackenzie (Nuremberg, Germany).

Subject: [PATCH] cc-mode: only the first clause of a for-loop should be checked for declarations
From: Daniel Colascione <[email-masked]>
To: [email-masked]
Date: Tue, 25 Jan 2011 22:36:22 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

// This code has no variable declarations

void foo() {
    for (; (DWORD) a * b ;)
        ;

    for (; a * b ;)
        ;
}
=== modified file 'lisp/progmodes/cc-fonts.el'
--- lisp/progmodes/cc-fonts.el	2010-12-07 12:15:28 +0000
+++ lisp/progmodes/cc-fonts.el	2011-01-25 11:10:00 +0000
@@ -1080,7 +1080,8 @@
 	  ;; o - '<> if the arglist is of angle bracket type;
 	  ;; o - 'arglist if it's some other arglist;
 	  ;; o - nil, if not in an arglist at all.  This includes the
-	  ;;   parenthesised condition which follows "if", "while", etc.
+	  ;;   parenthesised condition which follows "if", "while", etc.,
+	  ;;   but not "for", which is 'arglist after `;'.
 	  context
 	  ;; The position of the next token after the closing paren of
 	  ;; the last detected cast.
@@ -1109,7 +1110,7 @@
 	  ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
 	  ;; later fontification.
 	  (c-record-type-identifiers t)
-	  label-type
+	  label-type paren-state most-enclosing-brace
 	  c-record-ref-identifiers
 	  ;; Make `c-forward-type' calls mark up template arglists if
 	  ;; it finds any.  That's necessary so that we later will
@@ -1171,7 +1172,6 @@
 				 'font-lock-function-name-face))))
 	  (c-font-lock-function-postfix limit))
 
-	 
 	 (setq start-pos (point))
 	 (when
 	     ;; The result of the `if' condition below is true when we don't recognize a
@@ -1189,7 +1189,31 @@
 	    ;; (e.g. "for (").
 	    (let ((type (and (> match-pos (point-min))
 			     (c-get-char-property (1- match-pos) 'c-type))))
-	      (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
+	      (cond
+               (;; Try to not fontify the second and third clauses of
+		;; `for' statements as declarations.
+		(and (or (eq (char-before match-pos) ?\;)
+			 (save-excursion
+			   ;; Catch things like for(; (DWORD)(int) x &
+			   ;; y; ) without invoking the full might of
+			   ;; c-beginning-of-statement-1.
+			   (goto-char match-pos)
+			   (while (eq (char-before) ?\))
+			     (c-go-list-backward)
+			     (c-backward-syntactic-ws))
+			   (eq (char-before) ?\;)))
+		     
+                     (setq paren-state (c-parse-state))
+                     (setq most-enclosing-brace
+                           (c-most-enclosing-brace paren-state))
+		     (eq (char-after most-enclosing-brace) ?\())
+		
+                ;; After a ";" in a for-block. A declaration can never
+                ;; begin after a `;' if the most enclosing paren is a
+                ;; `('.
+		(setq context 'arglist
+                      c-restricted-<>-arglists t))
+               ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
 		     (setq context nil
 			   c-restricted-<>-arglists nil))
 		    ;; A control flow expression
@@ -1252,7 +1276,7 @@
 		;; Are we at a declarator?  Try to go back to the declaration
 		;; to check this.  Note that `c-beginning-of-decl-1' is slow,
 		;; so we cache its result between calls.
-		(let (paren-state bod-res encl-pos is-typedef)
+		(let (bod-res encl-pos is-typedef)
 		  (goto-char start-pos)
 		  (save-excursion
 		    (unless (and decl-search-lim
@@ -1318,20 +1342,7 @@
 		;; Back up to the type to fontify the declarator(s).
 		(goto-char (car decl-or-cast))
 
-		(let ((decl-list
-		       (if context
-			   ;; Should normally not fontify a list of
-			   ;; declarators inside an arglist, but the first
-			   ;; argument in the ';' separated list of a "for"
-			   ;; statement is an exception.
-			   (when (eq (char-before match-pos) ?\()
-			     (save-excursion
-			       (goto-char (1- match-pos))
-			       (c-backward-syntactic-ws)
-			       (and (c-simple-skip-symbol-backward)
-				    (looking-at c-paren-stmt-key))))
-			 t)))
-
+                (let ((decl-list (not context)))
 		  ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
 		  ;; before the first declarator if it's a list.
 		  ;; `c-font-lock-declarators' handles the rest.