Subject: bug#22156: CC Mode 5.33 (C++/l); Strange end-of-buffer error

From: Michael Welsh Duggan <[email-masked]>
Date: Fri, 18 Dec 2015 08:37:30 -0500

Alan Mackenzie <[email-masked]> writes:

> [Third attempt at sending; the first two bounced.  If this gets through,
> would you please add back the bug system address ([email-masked])
> as a CC when replying.]

I haven't yet had time to test this, but I got a couple other copies of
this message.  I would appreciate it if you let me know how they
bounced, so I can see if there are any problems in my mail system.

> Hello, Michael.
>
> On Sun, Dec 13, 2015 at 12:15:42AM -0500, Michael Welsh Duggan wrote:
>> Using emacs -Q /tmp/foo.cpp to start a new file, type the following:
>
>> struct foo<A<B,
>
>> When you type the comma, you should get an "End of buffer" error.  The
>> error seems to be at the point following this in the backtrace:
>
> Yes.  Thanks again for such a succinct bug report, and for the
> backtrace.  For some reason I couldn't get Emacs to give me a backtrace
> no matter what I tried.
>
>> Debugger entered--returning value: nil
>>   c-syntactic-re-search-forward("[<;{},|+&-]\\|[>)]" nil t t)
>> * c-forward-<>-arglist-recur(nil)
>> * c-forward-<>-arglist-recur(nil)
>> * c-forward-<>-arglist(nil)
>> * c-forward-name()
>> * c-forward-type(t)
>> * #[(preceding-token-end context last-cast-end)
>> "`\306\211\211\211\211\211\ ...
>> * apply(#[(preceding-token-end context last-cast-end)
>> "`\306\211\211\211\211\211 ...
>> * c-forward-decl-or-cast-1(1 nil nil)
>>   c-just-after-func-arglist-p(1)
>>   c-guess-basic-syntax()
>>   c-indent-line()
>>   c-electric-semi&comma(nil)
>>   funcall-interactively(c-electric-semi&comma nil)
>>   call-interactively(c-electric-semi&comma nil nil)
>>   command-execute(c-electric-semi&comma)
>
>
>> Emacs  : GNU Emacs 25.1.50.1 (x86_64-pc-linux-gnu, X toolkit)
>>  of 2015-11-26
>> Package: CC Mode 5.33 (C++/l)
>> Buffer Style: SiLK
>> c-emacs-features: (pps-extended-state col-0-paren posix-char-classes
>> gen-string-delim gen-comment-delim syntax-properties 1-bit)
>
> [ Dump of CC Mode's state snipped, but appreciated. ]
>
> The cause was a simple coding error: after searching forward (for a
> closing >), c-forward-<>-arglist-recur failed to set point back to the
> starting place before trying the next possibility.
>
> Here is a patch which I hope fixes things.  Please let me know whether
> or not it works satisfactorily.
>
>
>
> diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
> index acc2edd..11a0db2 100644
> --- a/lisp/progmodes/cc-engine.el
> +++ b/lisp/progmodes/cc-engine.el
> @@ -5964,7 +5964,7 @@ c-forward-<>-arglist-recur
>    ;; Recursive part of `c-forward-<>-arglist'.
>    ;;
>    ;; This function might do hidden buffer changes.
> -  (let ((start (point)) res pos tmp
> +  (let ((start (point)) res pos
>  	;; Cover this so that any recorded found type ranges are
>  	;; automatically lost if it turns out to not be an angle
>  	;; bracket arglist.  It's propagated through the return value
> @@ -6059,15 +6059,13 @@ c-forward-<>-arglist-recur
>  		  ;; Either an operator starting with '<' or a nested arglist.
>  		  (setq pos (point))
>  		  (let (id-start id-end subres keyword-match)
> -                  (cond
> +		    (cond
>  		     ;; The '<' begins a multi-char operator.
>  		     ((looking-at c-<-op-cont-regexp)
> -		      (setq tmp (match-end 0))
>  		      (goto-char (match-end 0)))
>  		     ;; We're at a nested <.....>
>  		     ((progn
> -			(setq tmp pos)
> -			(backward-char) ; to the '<'
> +			(backward-char)	; to the '<'
>  			(and
>  			 (save-excursion
>  			   ;; There's always an identifier before an angle
> @@ -6087,7 +6085,9 @@ c-forward-<>-arglist-recur
>  				  (and keyword-match
>  				       (c-keyword-member
>  					(c-keyword-sym (match-string 1))
> -					'c-<>-type-kwds)))))))
> +					'c-<>-type-kwds))))))
> +			(or subres (goto-char pos))
> +			subres)
>  		      ;; It was an angle bracket arglist.
>  		      (setq c-record-found-types subres)
>  
> @@ -6103,11 +6103,11 @@ c-forward-<>-arglist-recur
>  			    (c-record-ref-id (cons id-start id-end))
>                          (c-record-type-id (cons id-start id-end)))))
>  
> -                   ;; At a "less than" operator.
> -                   (t
> -                    (forward-char)
> -                    )))
> -                t)                    ; carry on looping.
> +		     ;; At a "less than" operator.
> +		     (t
> +		      ;; (forward-char) ; NO!  We've already gone over it.
> +		      )))
> +		  t)			; carry on looping.
>  
>  		 ((and (not c-restricted-<>-arglists)
>  		       (or (and (eq (char-before) ?&)
>
>
>
>> -- 
>> Michael Welsh Duggan
>> ([email-masked])

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