Subject: bug#43481: 27.1; cc-mode's c-context-line-break fails, inserting a new-line into the previous comment

From: Campbell Barton <[email-masked]>
Date: Thu, 26 Nov 2020 15:58:20 +1100

Hi Alan, thanks for fixing this,

Tested this both with `emacs -Q` and my personal (evil) config.

When your fix is applied, in both cases this works as expected.

On 11/25/20 2:02 AM, Alan Mackenzie wrote:
> Hello, Campbell.
> 
> Thank you indeed for taking the trouble to report this bug.
> 
> On Fri, Sep 18, 2020 at 09:38:16 +1000, Campbell Barton wrote:
>> Running 'c-context-line-break' sometimes adds the line break to the
>> previous comment, this seems to depend on the internal state
>> since it doesn't happen every time.
> 
> Yes.  The internal state it depends on is a cache for things like
> c-literal-limits (as you point out below).  To make the bug show itself,
> first type a space in the "A" comment somewhere (which clears the cache
> entries for any points after the place of the change), then move point
> into the B comment and type M-j.
> 
>> Tested in 27.1, and current master, this has been an issue for some
>> years IIRC.
> 
>> Take this example C file:
> 
>> ---- BEGIN `example.c`
>> /*
>>   * A
>>   */
> 
>> /*
>>   * B
>>   */
>> ---- END
> 
>> - Move the cursor the end-of-line above 'A'.
>> - M-x, c-context-line-break
> 
>> ----  `example.c` (with newline above 'A', as expected).
>> /*
>>   *
>>   * A
>>   */
> 
>> /*
>>   * B
>>   */
>> ---- END
> 
> [ .... ]
> 
>> ----
> 
>> I looked into the bug and this is caused by 'c-literal-limits'
>> returning an invalid range (where the beginning is correct, but the
>> end is the end of the previous comment, instead of the end of the
>> current comment).
> 
> Thank you very much indeed for taking the debugging so far.  That was
> exceptionally helpful.
> 
> What was happening was CC Mode read a cache entry, and because there was
> no entry for the "B" comment, got that for the "A" comment.  It later
> wrongly used the END element of that cache entry, without testing
> properly that it was valid.
> 
>> Printing 'c-literal-limits' before calling 'c-context-line-break'
>> shows this error, temporarily advising 'c-literal-limits' to return
>> the beginning/end of the comment is a workaround which
>> gives the 'EXPECTED RESULT'.
> 
> Yes.
> 
>> In GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.22,
>> cairo version 1.17.3)
>>   of 2020-08-29 built on juergen
>> Windowing system distributor 'The X.Org Foundation', version
>> 11.0.12009000
>> System Description: Arch Linux
> 
> [ .... ]
> 
> Would you please try the following patch in CC Mode.  After applying it,
> you need byte compile only cc-engine.el (which is in
> emacs/lisp/progmodes/).  In the unlikely event you would like any help
> with the patching or byte compilation, feel free to send me private
> email.
> 
> Having applied it, please test out the problem in your real code, and
> confirm that the bug is, in fact, fixed, or alternatively tell us that
> there are still glitches with it.  Thanks!
> 
> 
> 
> diff -r 4cdd79795247 cc-engine.el
> --- a/cc-engine.el	Sun Nov 15 10:19:11 2020 +0000
> +++ b/cc-engine.el	Tue Nov 24 14:53:07 2020 +0000
> @@ -3152,7 +3152,7 @@
>   		      ((nth 7 s) 'c++)
>   		      (t 'c)))
>   	    (setq start (nth 8 s))
> -	    (unless end
> +	    (unless (and end (>= end here))
>   	      (setq s1 (parse-partial-sexp here (point-max)
>   					   nil		  ; TARGETDEPTH
>   					   nil		  ; STOPBEFORE
> 
>