GNU bug report logs -
#39409
CC Mode 5.33.1 (C/*l); Wrong fontification of "foo * sizeof"
Previous Next
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 39409 in the body.
You can then email your comments to 39409 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Mon, 03 Feb 2020 23:03:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Benjamin Moody <benjaminmoody <at> gmail.com>
:
New bug report received and forwarded. Copy sent to
bug-cc-mode <at> gnu.org
.
(Mon, 03 Feb 2020 23:03:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
Emacs gives slightly odd fontification for the following C source:
int *foo(int length)
{
return malloc(length * sizeof(int));
}
In either C or C++ mode, the identifier 'length' in the third line is
formatted as a type name (font-lock-type-face). (In ObjC mode, this
doesn't happen.)
I'm not sure if this problem is limited to "identifier followed by '*'
followed by 'sizeof'", but that pattern occurs often enough to be
distinctive. :)
Emacs : GNU Emacs 26.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.5)
of 2019-09-22, modified by Debian
Package: CC Mode 5.33.1 (C/*l)
Buffer Style: gnu
c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)
current state:
==============
(setq
c-basic-offset 2
c-comment-only-line-offset '(0 . 0)
c-indent-comment-alist '((anchored-comment column . 0) (end-block space . 1)
(cpp-end-block space . 2))
c-indent-comments-syntactically-p nil
c-block-comment-prefix ""
c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+")
(other . "//+\\|\\**"))
c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc)
(c-mode . gtkdoc))
c-cleanup-list '(scope-operator)
c-hanging-braces-alist '((substatement-open before after)
(arglist-cont-nonempty))
c-hanging-colons-alist nil
c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
c-backslash-column 48
c-backslash-max-column 72
c-special-indent-hook '(c-gnu-impose-minimum)
c-label-minimum-indentation 1
c-offsets-alist '((inexpr-class . +)
(inexpr-statement . +)
(lambda-intro-cont . +)
(inlambda . c-lineup-inexpr-block)
(template-args-cont c-lineup-template-args +)
(incomposition . +)
(inmodule . +)
(innamespace . +)
(inextern-lang . +)
(composition-close . 0)
(module-close . 0)
(namespace-close . 0)
(extern-lang-close . 0)
(composition-open . 0)
(module-open . 0)
(namespace-open . 0)
(extern-lang-open . 0)
(objc-method-call-cont
c-lineup-ObjC-method-call-colons
c-lineup-ObjC-method-call
+
)
(objc-method-args-cont . c-lineup-ObjC-method-args)
(objc-method-intro . [0])
(friend . 0)
(cpp-define-intro c-lineup-cpp-define +)
(cpp-macro-cont . +)
(cpp-macro . [0])
(inclass . +)
(stream-op . c-lineup-streamop)
(arglist-cont-nonempty
c-lineup-gcc-asm-reg
c-lineup-arglist
)
(arglist-cont c-lineup-gcc-asm-reg 0)
(comment-intro
c-lineup-knr-region-comment
c-lineup-comment
)
(catch-clause . 0)
(else-clause . 0)
(do-while-closure . 0)
(access-label . -)
(case-label . 0)
(substatement . +)
(statement-case-intro . +)
(statement . 0)
(brace-entry-open . 0)
(brace-list-close . 0)
(block-close . 0)
(block-open . 0)
(inher-cont . c-lineup-multi-inher)
(inher-intro . +)
(member-init-cont . c-lineup-multi-inher)
(member-init-intro . +)
(annotation-var-cont . +)
(annotation-top-cont . 0)
(topmost-intro . 0)
(knr-argdecl . 0)
(func-decl-cont . +)
(inline-close . 0)
(class-close . 0)
(class-open . 0)
(defun-block-intro . +)
(defun-close . 0)
(defun-open . 0)
(c . c-lineup-C-comments)
(string . c-lineup-dont-change)
(topmost-intro-cont
first
c-lineup-topmost-intro-cont
c-lineup-gnu-DEFUN-intro-cont
)
(brace-list-open . +)
(inline-open . 0)
(arglist-close . c-lineup-arglist)
(arglist-intro . c-lineup-arglist-intro-after-paren)
(statement-cont . +)
(statement-case-open . +)
(label . 0)
(substatement-label . 0)
(substatement-open . +)
(knr-argdecl-intro . 5)
(statement-block-intro . +)
(brace-list-intro . +)
(brace-list-entry . 0)
)
c-buffer-is-cc-mode 'c-mode
c-tab-always-indent t
c-syntactic-indentation t
c-syntactic-indentation-in-macros t
c-ignore-auto-fill '(string cpp code)
c-auto-align-backslashes t
c-backspace-function 'backward-delete-char-untabify
c-delete-function 'delete-char
c-electric-pound-behavior nil
c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu"))
c-enable-xemacs-performance-kludge-p nil
c-old-style-variable-behavior nil
defun-prompt-regexp nil
tab-width 8
comment-column 32
parse-sexp-ignore-comments t
parse-sexp-lookup-properties t
auto-fill-function nil
comment-multi-line t
comment-start-skip "\\(//+\\|/\\*+\\)\\s *"
fill-prefix nil
fill-column 70
paragraph-start "[ ]*\\(//+\\|\\**\\)[ ]*$\\|^\f"
adaptive-fill-mode t
adaptive-fill-regexp "[ ]*\\(//+\\|\\**\\)[ ]*\\([ ]*\\([-–!|#%;>*·•‣⁃◦]+[ ]*\\)*\\)"
)
Information forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Wed, 05 Feb 2020 20:58:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 39409 <at> debbugs.gnu.org (full text, mbox):
Hello, Benjamin.
Thank you for taking the trouble to report this bug, and thanks even
more for appending a full CC-Mode configuration dump from C-c C-b.
On Mon, Feb 03, 2020 at 18:02:22 -0500, Benjamin Moody wrote:
> Emacs gives slightly odd fontification for the following C source:
> int *foo(int length)
> {
> return malloc(length * sizeof(int));
> }
> In either C or C++ mode, the identifier 'length' in the third line is
> formatted as a type name (font-lock-type-face). (In ObjC mode, this
> doesn't happen.)
The problem was actually fixed in 2017, but hasn't yet made it through
to a released version of Emacs.
> I'm not sure if this problem is limited to "identifier followed by '*'
> followed by 'sizeof'", but that pattern occurs often enough to be
> distinctive. :)
The problem was an awkward ambiguity, where
foo * bar(baz)
could be either a multiplication of foo by the result of calling bar, or
the declaration of a function bar taking a parameter of type baz and
returning a pointer to something of type foo.
One really needs semantic analysis to resolve this properly, but until
that happens, the workaround adopted is to use the (a)symmetry of
whitespace around the * operator - If we have one of
foo * bar(baz)
foo*bar(baz)
we treat the * as a mulplication. If we have one of
foo *bar(baz)
foo* bar(baz)
the whole thing is a function declaration. This seems to work, more or
less, in most cases.
I would recommend you to upgrade your CC Mode. There are several ways
to do this, in order of increasing work to you:
1/- Wait until the release of Emacs 27.1. This will be several months
away, but probably less than a year.
2/- Ask me to send you a tarball of the current CC Mode in Emacs.
3/- Download the last released standalone CC Mode 5.34 from
http://cc-mode.sourceforge.net/ (Note: the standalone version and that
in Emacs have drifted apart, somewhat).
4/- Get the head of the Mercurial repository at the above address.
5/- Check out the entire Emacs repository from https://savannah.gnu.org,
and use the not-quite-in-pretest Emacs version 27.
6/- Extract the CC Mode sources from the Emacs repository, and use those
in Emacs 26.
In all these methods apart from the first, you will need to byte compile
the CC Mode sources (which isn't difficult).
> Emacs : GNU Emacs 26.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.5)
> of 2019-09-22, modified by Debian
> Package: CC Mode 5.33.1 (C/*l)
> Buffer Style: gnu
> c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)
[ .... ]
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Thu, 06 Feb 2020 04:40:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 39409 <at> debbugs.gnu.org (full text, mbox):
Hi,
Thank you for all your work on CC Mode. And yeah, I know C syntax can
get pretty hairy. :)
The curious thing is, though, this issue doesn't seem to occur with
"foo * bar(baz)". What I'm seeing seems to happen specifically when
the "function" is actually a keyword (like sizeof), and the expression
is enclosed in parentheses:
void foo()
{
xxx(xxx * xxx(xxx)); /* correct */
xxx(ttt * sizeof(xxx)); /* wrong */
xxx(xxx, xxx * xxx(xxx)); /* correct */
xxx(xxx, ttt * sizeof(xxx)); /* wrong */
ttt * fff(xxx); /* ambiguous, but logical */
xxx * sizeof(xxx); /* correct */
(xxx * xxx(xxx)); /* correct */
(ttt * sizeof(xxx)); /* wrong */
xxx = xxx * xxx(xxx); /* correct */
xxx = xxx * sizeof(xxx); /* correct */
xxx = (ttt * fff(xxx)); /* wrong (I think) */
xxx = (xxx * sizeof(xxx)); /* correct */
}
(In these examples, 'xxx' uses the default face, 'ttt' uses
font-lock-type-face, 'fff' uses font-lock-function-name-face, and of
course 'sizeof' uses font-lock-keyword-face.)
I tried the standalone version (cc-mode-5.34.tar.gz) and it appears to
give the same results as above.
Benjamin
Information forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Thu, 06 Feb 2020 20:22:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 39409 <at> debbugs.gnu.org (full text, mbox):
Hello again, Benjamin.
Apologies for answering your original post rather hastily. CC Mode 5.34
does indeed leave wrong fontifications as you have noted below. I'd
forgotten a particular patch I'd made since 5.34 which has a bearing on
these fontifications. This was
changeset: 6660:19eb4ddc766b
tag: 2019-09-16-dix-m
user: Alan Mackenzie <bug-cc-mode <at> gnu.org>
date: Sat Sep 21 12:11:27 2019 +0000
files: cc-engine.el tests/statement-29.cc tests/statement-29.face
description:
CC Mode: Fix wrong fontification of FOO in ASSERT (FOO && !BAR)
from the CC Mode Mercurial repository at SourceForge.
Could I ask you, please, to apply this patch to your copy of CC Mode
5.34:
diff -r a5dbcca7730b -r 19eb4ddc766b cc-engine.el
--- a/cc-engine.el Sat Sep 21 12:09:54 2019 +0000
+++ b/cc-engine.el Sat Sep 21 12:11:27 2019 +0000
@@ -10109,7 +10109,8 @@
(throw 'at-decl-or-cast t)))))
;; CASE 18
- (when (and (not (memq context '(nil top)))
+ (when (and at-decl-end
+ (not (memq context '(nil top)))
(or (and got-prefix (not got-number))
(and (eq context 'decl)
(not c-recognize-paren-inits)
On Wed, Feb 05, 2020 at 23:57:13 +0000, Benjamin Moody wrote:
> Hi,
> Thank you for all your work on CC Mode. And yeah, I know C syntax can
> get pretty hairy. :)
> The curious thing is, though, this issue doesn't seem to occur with
> "foo * bar(baz)". What I'm seeing seems to happen specifically when
> the "function" is actually a keyword (like sizeof), and the expression
> is enclosed in parentheses:
With the above patch in place and cc-engine.el recompiled, the
fontification of your test file from yesterday seems to be correct. In
particular:
> void foo()
> {
> xxx(xxx * xxx(xxx)); /* correct */
> xxx(ttt * sizeof(xxx)); /* wrong */
> xxx(xxx, xxx * xxx(xxx)); /* correct */
> xxx(xxx, ttt * sizeof(xxx)); /* wrong */
These two "wrong" lines are now fontified correctly.
> ttt * fff(xxx); /* ambiguous, but logical */
Indeed. Being at the "top level", this can only be a declaration. If
you put "foo = " in front of that line, turning it into a statement, the
fontifications on ttt and fff disappear.
> xxx * sizeof(xxx); /* correct */
> (xxx * xxx(xxx)); /* correct */
> (ttt * sizeof(xxx)); /* wrong */
This one is now correct.
> xxx = xxx * xxx(xxx); /* correct */
> xxx = xxx * sizeof(xxx); /* correct */
> xxx = (ttt * fff(xxx)); /* wrong (I think) */
> xxx = (xxx * sizeof(xxx)); /* correct */
Here ttt gets type face because a previous ttt has been recognised as a
type and entered into CC Mode's "found types" mechanism. If you change
this ttt into tttt, the wrong fontification disappears, since tttt is
not registered as a "found type".
> }
> (In these examples, 'xxx' uses the default face, 'ttt' uses
> font-lock-type-face, 'fff' uses font-lock-function-name-face, and of
> course 'sizeof' uses font-lock-keyword-face.)
> I tried the standalone version (cc-mode-5.34.tar.gz) and it appears to
> give the same results as above.
Yes. Sorry once again for not being more careful in my first reply.
> Benjamin
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Fri, 07 Feb 2020 17:48:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 39409 <at> debbugs.gnu.org (full text, mbox):
Hi,
> diff -r a5dbcca7730b -r 19eb4ddc766b cc-engine.el
> --- a/cc-engine.el Sat Sep 21 12:09:54 2019 +0000
> +++ b/cc-engine.el Sat Sep 21 12:11:27 2019 +0000
> @@ -10109,7 +10109,8 @@
> (throw 'at-decl-or-cast t)))))
>
> ;; CASE 18
> - (when (and (not (memq context '(nil top)))
> + (when (and at-decl-end
> + (not (memq context '(nil top)))
> (or (and got-prefix (not got-number))
> (and (eq context 'decl)
> (not c-recognize-paren-inits)
Yes, this patch fixes the issue. Thanks once again!
Benjamin
Information forwarded
to
bug-cc-mode <at> gnu.org
:
bug#39409
; Package
cc-mode
.
(Fri, 07 Feb 2020 20:02:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 39409 <at> debbugs.gnu.org (full text, mbox):
close 39409 27.0.60
quit
Hello again, Benjamin.
On Fri, Feb 07, 2020 at 17:47:33 +0000, Benjamin Moody wrote:
> Hi,
> > diff -r a5dbcca7730b -r 19eb4ddc766b cc-engine.el
> > --- a/cc-engine.el Sat Sep 21 12:09:54 2019 +0000
> > +++ b/cc-engine.el Sat Sep 21 12:11:27 2019 +0000
> > @@ -10109,7 +10109,8 @@
> > (throw 'at-decl-or-cast t)))))
> > ;; CASE 18
> > - (when (and (not (memq context '(nil top)))
> > + (when (and at-decl-end
> > + (not (memq context '(nil top)))
> > (or (and got-prefix (not got-number))
> > (and (eq context 'decl)
> > (not c-recognize-paren-inits)
> Yes, this patch fixes the issue. Thanks once again!
Thank you for the test. The patch in question is already in the
emacs-27 branch, so I think we can regard the bug as fixed. I'm closing
it with this post.
> Benjamin
--
Alan Mackenzie (Nuremberg, Germany).
bug marked as fixed in version 27.0.60, send any further explanations to
39409 <at> debbugs.gnu.org and Benjamin Moody <benjaminmoody <at> gmail.com>
Request was from
Alan Mackenzie <acm <at> muc.de>
to
control <at> debbugs.gnu.org
.
(Fri, 07 Feb 2020 20:02:02 GMT)
Full text and
rfc822 format available.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sat, 07 Mar 2020 12:24:04 GMT)
Full text and
rfc822 format available.
This bug report was last modified 5 years and 161 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.