[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Getting the correct line/column numbers on byte compilation error/warnin

From: Alan Mackenzie
Subject: Getting the correct line/column numbers on byte compilation error/warning messages
Date: Sun, 16 Jul 2017 13:44:29 +0000
User-agent: Mutt/1.7.2 (2016-11-26)

Hello, Emacs.

The line/column numbers currently output by the byte compiler are not
rigorous - they sort of work most of the time.  When they don't work, we
get bug #24449, or bug #2681, or bug #8774, or bug #9109, or bug #22288,
or bug #24128.  Clearly a solution to this would be popular.

The reason for all these bugs is the mechanism in the byte compiler
where the reader stores the location of each occurrence of each symbol
in a list.  "Each" time the byte compiler encounters a symbol, the
earlier occurrences of that symbol are discarded from the pertinent
list, leaving the location of the next element as the location for the
error/warning message.  This is a "gross hack" which sometimes causes
the wrong line/column numbers to be output in error/warning messages.

I've been working on a replacement, and although I don't yet have
anything to show, I'd like to describe what I have.

I've modified lread.c so that when an enabling flag is set, it records
the source offset of each cons or vector in a hash table.  The key to
the table is the cons cell/vector, and the value is the offset (more or
less).  After each read operation, the "top structure" is recorded in
global variables, `read-outer-form' and `read-outer-loc'.  (The latter
is non-nil when the former refers to the cdr of a dotted pair, or an
element of a vector.)

As the compilation proceeds recursively, `read-outer-form/loc' are bound
to successively more enclosed forms.  Should an error or warning occur,
the line and column numbers are taken from these two variables via the
hash table.

This is all well and good.  The implementation is problematic, largely
because currently, the compilation optimises by ripping the original
form apart and sticking it back together again in new conses.  This
breaks the mechanism for accessing location information from the hash
table, whose keys are the original cons cells.

I've worked out some primitive functions which do what standard
functions do, but store their results in specified cons cells.  For

    (defun bo-cons (kar kdr dest)
      "Return a cons of KAR and KDR.  This cons will be DEST, with its
    car and cdr overwritten."
      (setcar dest kar)
      (setcdr dest kdr)
      (setq bo-fixed t)

(The prefix "bo-" is at the moment purely for convenience, and the
variable `bo-fixed' is used to indicate change to a structure, because
the comparison (eq newform form) would now always return t.)

I've amended many of the functions in byte-opt.el to use only
cons-preserving primitives, though, as yet, I haven't tested them much.

What do people think?

Alan Mackenzie (Nuremberg, Germany).

reply via email to

[Prev in Thread] Current Thread [Next in Thread]