compiler: better checking whether a variable may be introduced

Previously c1make-var checked whether the symbol NAME is CONSTANTP, but
ECL expands symbol macros in CONSTANTP so this returned false positives.
A similar concern applied to the CMP-ENV-REGISTER-SYMBOL-MACRO-FUNCTION.

C1EXPR-INNER when encountered a symbol tried to yield C1CONSTANT-VALUE
for if it iwas CONSTANTP - this was correct except for that we didn't
pass the environment to the predicate and symbols weren't shadowed.

In this commit one function is added to the core - si:constp (with
similar purpose to si:specialp) and one function to the compiler -
constant-variable-p (similar to special-variable-p) and they are
appropriately used when necessary. A regression test is added.

Fixes #662.
This commit is contained in:
Daniel Kochmański 2021-11-19 11:56:23 +01:00
parent de1b587d78
commit 6aa02de4c4
8 changed files with 30 additions and 4 deletions

View file

@ -152,7 +152,7 @@ the closure in let/flet forms for variables/functions it closes over."
env))
(defun cmp-env-register-symbol-macro-function (name function &optional (env *cmp-env*))
(when (or (constantp name) (special-variable-p name))
(when (or (constant-variable-p name) (special-variable-p name))
(cmperr "Cannot bind the special or constant variable ~A with symbol-macrolet." name))
(push (list name 'si::symbol-macro function)
(cmp-env-variables env))

View file

@ -25,7 +25,7 @@
((keywordp form)
(make-c1form* 'LOCATION :type (object-type form)
:args (add-symbol form)))
((constantp form)
((constantp form *cmp-env*)
(or (c1constant-value (symbol-value form) :only-small-values t)
(c1var form)))
(t (c1var form))))

View file

@ -221,7 +221,7 @@
(defun c1make-var (name specials ignores types)
(cmpck (not (symbolp name)) "The variable ~s is not a symbol." name)
(cmpck (constantp name) "The constant ~s is being bound." name)
(cmpck (constant-variable-p name) "The constant ~s is being bound." name)
(let ((ignorable (cdr (assoc name ignores)))
(kind 'LEXICAL) ; we rely on check-vref to fix it
(type (assoc name types)))

View file

@ -222,6 +222,9 @@
;; we also have to consider 'GLOBAL here.
(and v (eq (var-kind v) 'SPECIAL)))))
(defun constant-variable-p (name)
(si::constp name))
(defun local-variable-p (name &optional (env *cmp-env*))
(let ((record (cmp-env-search-var name env)))
(and record (var-p record))))