Subject: Re: bug#19206: 25.0.50; CC Mode tracks wrong source files

From: Alan Mackenzie <[email-masked]>
Date: 28 Nov 2014 22:25:42 -0000

Hello, Sebastian.
In article <[email-masked]> you wrote:
> CC Mode tracks wrong source files when a CC Mode derived mode is
> installed non-interactively.

The rest of your post describes your detective work to track down the
problem, which is brilliant.  But you haven't said what the problem itself
is, at least not in high level terms.

What does the file look like which does the non-interactive installation,
when do you see an error, and what is this error message?

> To reproduce, save the following code as `cc-miscompile.el'

> (require 'package)
> (require 'cc-defs)

> (defun main ()
>  (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))

>  (setq package-user-dir (make-temp-file "cc-miscompile" 'directory))

>  (package-initialize)
>  (package-refresh-contents)
>  (package-install 'd-mode)

>  (require 'd-mode)

>  (let ((source (get (intern "c-typedef-decl-kwds" c-lang-constants) 'source)))
>    (message "Sources: %S" (mapcar 'car source)))

>  (delete-directory package-user-dir 'recursive))

> (main)

> and run it with `emacs -Q --script cc-miscompile.el'.  The output is as
> follows (package.el output shortened for readility):

> Contacting host: melpa.org:80
> Contacting host: elpa.gnu.org:80
> [?]
> Sources: (d-mode cc-miscompile cc-langs)

> Note that `cc-miscompile' ends up in the source list of
> `c-typedef-decl-kwds', even though it never actually calls any `c-*'
> functions at all.

The byte compilation of d-mode.el is being done during the loading of
cc-miscompile.el.  This somewhat unusual constellation, I think, is
causing the problem.  When CC Mode determines the file name to put onto
a c-lang-defconst's 'source property, it gives priority to the load file
name, and only when this is nil does it use the byte-compile file name.
(This is in defsubst c-get-current-file in cc-defs.el).  It would seem
this is not the correct priority.

I think swapping the first two arms of the `cond' form in
c-get-current-file may solve the problem.  It's a bit late to try this
tonight, I'll try it tomorrow.

> Naturally, CC Mode will later try to load this file, and fail if it is
> not in the `load-path'.  This effectively breaks installations of D
> Mode from non-interactive Emacs sessions.

> I did not try to find the culprit.  The CC Mode code is convoluted
> beyond my understanding.

The mechanism for the c-lang-defvar's may appear complicated, but it this
concentration of the complexity in a single place that enables the simple,
tabular definition of language dependent constants, even (especially) in
derived modes.

-- 
Alan Mackenzie (Nuremberg, Germany).