mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-26 06:22:33 -08:00
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:
parent
de1b587d78
commit
6aa02de4c4
8 changed files with 30 additions and 4 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))))
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue