In *scratch*, evaluate:
(defvar foo-test-var nil)
(with-temp-buffer
(list (list (buffer-local-value 'foo-test-var (current-buffer))
(local-variable-p 'foo-test-var)
(local-variable-if-set-p 'foo-test-var))
(cl-letf (((buffer-local-value 'foo-test-var (current-buffer)) 123))
(list (buffer-local-value 'foo-test-var (current-buffer))
(local-variable-p 'foo-test-var)
(local-variable-if-set-p 'foo-test-var)))
(list (buffer-local-value 'foo-test-var (current-buffer))
(local-variable-p 'foo-test-var)
(local-variable-if-set-p 'foo-test-var))))
The result is:
((nil nil nil) (123 t t) (nil t t))
But expected is:
((nil nil nil) (123 t t) (nil nil nil))
i.e. the local flag of the variable should be reset.
It's possible to fix this (see attached patch), but at the expense of breaking other valid use cases such as (cl-incf (buffer-local-value ...)). Not sure whether the bug can be fixed at all without breaking other stuff.