Don't warn when #'(setf fun) is used in the presence of a setf-macro.
[sbcl.git] / src / compiler / constantp.lisp
index 29252c2..d06d226 100644 (file)
@@ -29,7 +29,7 @@
 
 (defun %constantp (form environment envp)
   (let ((form (if envp
-                  (sb!xc:macroexpand form environment)
+                  (%macroexpand form environment)
                   form)))
     (typecase form
       ;; This INFO test catches KEYWORDs as well as explicitly
       (list
        (or (constant-special-form-p form environment envp)
            #-sb-xc-host
-           (constant-function-call-p form environment envp)))
+           (values (constant-function-call-p form environment envp))))
       (t t))))
 
 (defun %constant-form-value (form environment envp)
   (let ((form (if envp
-                  (sb!xc:macroexpand form environment)
+                  (%macroexpand form environment)
                   form)))
     (typecase form
       (symbol
-       (symbol-value form))
+       ;; KLUDGE: superficially, this might look good enough: we grab
+       ;; the value from the info database, and if it isn't there (or
+       ;; is NIL, but hey) we use the host's value.  This works for
+       ;; MOST-POSITIVE-FIXNUM and friends, but still fails for
+       ;; float-related constants, where there is in fact no guarantee
+       ;; that we can represent our target value at all in the host,
+       ;; so we don't try.  We should rework all uses of floating
+       ;; point so that we never try to use a host's value, and then
+       ;; make some kind of assertion that we never attempt to take
+       ;; a host value of a constant in the CL package.
+       #+sb-xc-host (or (info :variable :xc-constant-value form)
+                        (symbol-value form))
+       #-sb-xc-host (symbol-value form))
       (list
        (if (special-operator-p (car form))
            (constant-special-form-value form environment envp)
 ;;; too.
 (defun constant-function-call-p (form environment envp)
   (let ((name (car form)))
-    (and (legal-fun-name-p name)
-         (eq :function (info :function :kind name))
-         (let ((info (info :function :info name)))
-           (and info (ir1-attributep (fun-info-attributes info)
-                                     foldable)))
-         (and (every (lambda (arg)
-                       (%constantp arg environment envp))
-                     (cdr form))
-              ;; Even though the function may be marked as foldable
-              ;; the call may still signal an error -- eg: (CAR 1).
-              (handler-case
-                  (progn
-                    (constant-function-call-value form environment envp)
-                    t)
-                (error () nil))))))
+    (if (and (legal-fun-name-p name)
+             (eq :function (info :function :kind name))
+             (let ((info (info :function :info name)))
+               (and info (ir1-attributep (fun-info-attributes info)
+                                         foldable)))
+             (and (every (lambda (arg)
+                           (%constantp arg environment envp))
+                         (cdr form))))
+        ;; Even though the function may be marked as foldable
+        ;; the call may still signal an error -- eg: (CAR 1).
+        (handler-case
+            (values t (constant-function-call-value form environment envp))
+          (error ()
+            (values nil nil)))
+        (values nil nil))))
 
 (defun constant-function-call-value (form environment envp)
   (apply (fdefinition (car form))