* src/data.c (Fmake_local_variable): Fix bug#34318

Revert part of ed962f2b8a.

* test/src/data-tests.el (data-tests-make-local-forwarded-var):
Add corresponding test.
This commit is contained in:
Stefan Monnier 2019-02-12 16:33:23 -05:00
parent b384996e86
commit 3f4b8e9a29
2 changed files with 28 additions and 0 deletions

View file

@ -1954,6 +1954,16 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
(current_buffer,
Fcons (Fcons (variable, XCDR (blv->defcell)),
BVAR (current_buffer, local_var_alist)));
/* If the symbol forwards into a C variable, then load the binding
for this buffer now, to preserve the invariant that forwarded
variables must always hold the value corresponding to the
current buffer (they are swapped eagerly).
Otherwise, if C code modifies the variable before we load the
binding in, then that new value would clobber the default binding
the next time we unload it. See bug#34318. */
if (blv->fwd)
swap_in_symval_forwarding (sym, blv);
}
return variable;

View file

@ -508,4 +508,22 @@ comparing the subr with a much slower lisp implementation."
(bound-and-true-p data-tests-foo2)
(bound-and-true-p data-tests-foo3)))))))
(ert-deftest data-tests-make-local-forwarded-var () ;bug#34318
;; Boy, this bug is tricky to trigger. You need to:
;; - call make-local-variable on a forwarded var (i.e. one that
;; has a corresponding C var linked via DEFVAR_(LISP|INT|BOOL))
;; - cause the C code to modify this variable from the C side of the
;; forwarding, but this needs to happen before the var is accessed
;; from the Lisp side and before we switch to another buffer.
;; The trigger in bug#34318 doesn't exist any more because the C code has
;; changes. Instead I found the trigger below.
(with-temp-buffer
(setq last-coding-system-used 'bug34318)
(make-local-variable 'last-coding-system-used)
;; This should set last-coding-system-used to `no-conversion'.
(decode-coding-string "hello" nil)
(should (equal (list last-coding-system-used
(default-value 'last-coding-system-used))
'(no-conversion bug34318)))))
;;; data-tests.el ends here