From 337bd9a3e8992070e4a15d67df7a47e6414f50f6 Mon Sep 17 00:00:00 2001 From: Douglas Katzman Date: Mon, 24 Jul 2017 23:38:00 -0400 Subject: [PATCH] Resolve chicken-and-egg problem with SYMBOL-VALUE. Don't transform (SYMBOL-VALUE 'X) -> X -> (SYMBOL-VALUE 'X) Fixes problem with FLEXI-STREAMS::DEFCONSTANT --- src/compiler/srctran.lisp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index c563a3a67..50928c32a 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -5010,9 +5010,21 @@ ((:early :late) (unless (gethash symbol *free-vars*) (setf (gethash symbol *free-vars*) :deprecated))))) - ;; :global in the MEMQ test is redundant if match-kind is :global + ;; :global in the test below is redundant if match-kind is :global ;; but it's harmless and a convenient way to express this. - (when (or (eq kind match-kind) (memq kind '(:constant :global))) + ;; Note that some 3rd-party libraries use variations on DEFCONSTANT + ;; expanding into expressions such as: + ;; (CL:DEFCONSTANT S (IF (BOUNDP 'S) (SYMBOL-VALUE 'S) (COMPUTE))) + ;; which means we have to use care if S in for-evaluation position would + ;; be converted to (LOAD-TIME-VALUE (SYMBOL-VALUE 'S)). + ;; When S's value is directly dumpable, it works fine, but otherwise + ;; it's dangerous. If the user wishes to avoid eager evaluation entirely, + ;; a local notinline declaration on SYMBOL-VALUE will do. + (when (or (eq kind match-kind) + (eq kind :global) + (and (eq kind :constant) + (boundp symbol) + (typep (symbol-value symbol) '(or number character symbol)))) (return-from xform symbol)))) fallback)) (deftransform symbol-global-value ((symbol)) -- 2.11.4.GIT