Subject: bug#29293: CC Mode 5.33 (C//l); c-display-defun-name echoes return type not name of function

From: Alan Mackenzie <[email-masked]>
Date: Thu, 16 Nov 2017 21:59:16 +0000

Hello, Basil.

On Tue, Nov 14, 2017 at 13:03:44 +0000, Basil L. Contovounesios wrote:

> Steps to reproduce:

> 1. emacs -Q
> 2. M-x find-function RET current-column RET
>    (i.e. visit file src/indent.c)
> 3. M-g g 59 RET
>    (i.e. move point to start of function
>    buffer_display_table)
> 4. C-c C-z

> Expected result: Message "buffer_display_table.  Line 1/12."
> Actual result: Message "struct Lisp_Char_Table.  Line 1/12."

Yes.

Thank you very much for taking the trouble to report this bug.

What is happening is that inside the CC Mode function c-defun-name, 

    struct Lisp_Char_Table *
    buffer_display_table (void)
    {

is triggering the "cond arm" (the lisp equivalent of C's switch case)
which picks up declarations of structs, etc., rather than the cond arm
dealing with functions.

The following provisional patch tightens up the analysis, so I hope it
solves the bug.

The reason I say provisional is that in the following fragment (which is
an unusual thing to write):

    struct foo {
        int bar;
    } baz (int fred)
    {
        return barney;
    }

with point on the } in line 3, C-c C-z triggers an error.  With point at
other places, C-c C-z returns the correct "baz".

Anyhow, could I ask you, please, to apply the patch, recompile
cc-cmds.el, and try it out in any other code you found the bug in, and
let me know if the bug is indeed fixed.  In the meantime, I'll work on
fixing the error in the analysis of that code fragment.

(If you want any help in applying the patch or compiling cc-cmds.el,
please feel free to send me private mail).

diff -r 52dfb2eca185 cc-cmds.el
--- a/cc-cmds.el	Sun Nov 12 11:32:27 2017 +0000
+++ b/cc-cmds.el	Thu Nov 16 21:50:47 2017 +0000
@@ -1804,7 +1804,15 @@
 	  ;; Pick out the defun name, according to the type of defun.
 	  (cond
 	   ;; struct, union, enum, or similar:
-	   ((looking-at c-type-prefix-key)
+	   ((save-excursion
+	      (and
+	       (looking-at c-type-prefix-key)
+	       (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
+	       (or (not (or (eq (char-after) ?{)
+			    (and c-recognize-knr-p
+				 (c-in-knr-argdecl))))
+		   (progn (c-backward-syntactic-ws)
+			  (not (eq (char-before) ?\)))))))
 	    (let ((key-pos (point)))
 	      (c-forward-over-token-and-ws) ; over "struct ".
 	      (cond
@@ -1834,8 +1842,16 @@
 		
 	   (t
 	    ;; Normal function or initializer.
-	    (when (c-syntactic-re-search-forward "[{(]" nil t)
-	      (backward-char)
+	    (when
+		(and
+		 (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
+		 (or (eq (char-after) ?{)
+		     (and c-recognize-knr-p
+			  (c-in-knr-argdecl)))
+		 (progn
+		   (c-backward-syntactic-ws)
+		   (eq (char-before) ?\)))
+		 (c-go-list-backward))
 	      (c-backward-syntactic-ws)
 	      (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
 		(c-backward-token-2)

[ .... ]

> The information collected by c-submit-bug-report follows my
> signature.

This is appreciated, thanks, even though I've snipped it.  ;-)

> Thanks,

> -- 
> Basil

-- 
Alan Mackenzie (Nuremberg, Germany).