master: More thorough tracking of macro argument modifications

stassats via Sbcl-commits <[email protected]>
Newsgroups gmane.lisp.steel-bank.cvs
Message-ID <[email protected]>
The branch "master" has been updated in SBCL:
       via  5bfa2103ecc8139ef53198d71d32f5ac67ab1925 (commit)
      from  c3389405764a66412dc4bad86d133fb520bdddd8 (commit)

- Log -----------------------------------------------------------------
commit 5bfa2103ecc8139ef53198d71d32f5ac67ab1925
Author: Stas Boukarev <[email protected]>
Date:   Sun Aug 30 04:16:57 2026 +0300

    More thorough tracking of macro argument modifications
---
 src/compiler/ir1util.lisp | 35 +++++++++++++++++------------------
 tests/bad-code.pure.lisp  |  9 +++++++++
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/compiler/ir1util.lisp b/src/compiler/ir1util.lisp
index 33649646f..fdd35f985 100644
--- a/src/compiler/ir1util.lisp
+++ b/src/compiler/ir1util.lisp
@@ -3839,15 +3839,7 @@ is :ANY, the function name is not checked."
 
 (defun lvar-constants (lvar &optional walk-functions)
   (named-let recurse ((lvar lvar) (seen nil))
-    (let* ((uses (lvar-uses lvar))
-           (lvar (or (and (ref-p uses)
-                          (let ((ref (principal-lvar-ref lvar)))
-                            (and ref
-                                 (or
-                                  (lambda-var-ref-lvar ref)
-                                  (node-lvar ref)))))
-                     lvar))
-           (uses (lvar-uses lvar)))
+    (let ((uses (lvar-uses lvar)))
       (flet ((handle-ref (ref)
                (let* ((ref (principal-ref ref))
                       (leaf (and ref
@@ -3886,6 +3878,14 @@ is :ANY, the function name is not checked."
                (values :values (list (lvar-value lvar))))
               ((constant-lvar-uses-p lvar)
                (values :values (lvar-uses-values lvar)))
+              ((loop for annot in (lvar-annotations lvar)
+                     when (lvar-lambda-var-annotation-p annot)
+                     do (let ((lambda-var (lvar-lambda-var-annotation-lambda-var annot)))
+                          (when (and (lambda-var-constant lambda-var)
+                                     (not (lambda-var-sets lambda-var)))
+                            (return-from
+                             lvar-constants
+                              (values :macro lambda-var))))))
               ((ref-p uses)
                (handle-ref uses))
               (walk-functions
@@ -3921,15 +3921,6 @@ is :ANY, the function name is not checked."
         (leaf-debug-name leaf))))
 
 (defun process-lvar-modified-annotation (lvar annotation)
-  (loop for annot in (lvar-annotations lvar)
-        when (lvar-lambda-var-annotation-p annot)
-        do (let ((lambda-var (lvar-lambda-var-annotation-lambda-var annot)))
-             (when (and (lambda-var-constant lambda-var)
-                        (not (lambda-var-sets lambda-var)))
-               (warn 'sb-kernel::macro-arg-modified
-                     :fun-name (lvar-modified-annotation-caller annotation)
-                     :variable (lambda-var-original-name lambda-var))
-               (return-from process-lvar-modified-annotation))))
   (multiple-value-bind (type values) (lvar-constants lvar t)
     (labels ((modifiable-p (value)
                (or (consp value)
@@ -3944,6 +3935,14 @@ is :ANY, the function name is not checked."
                         :fun-name (lvar-modified-annotation-caller annotation)
                         :values sans-nil)))))
      (case type
+       (:macro
+        (let ((lambda-var values))
+          (when (and (lambda-var-constant lambda-var)
+                     (not (lambda-var-sets lambda-var)))
+            (warn 'sb-kernel::macro-arg-modified
+                  :fun-name (lvar-modified-annotation-caller annotation)
+                  :variable (lambda-var-original-name lambda-var))
+            (return-from process-lvar-modified-annotation))))
        (:values
         (report values)
         t)
diff --git a/tests/bad-code.pure.lisp b/tests/bad-code.pure.lisp
index b75c7563c..e0c2708f4 100644
--- a/tests/bad-code.pure.lisp
+++ b/tests/bad-code.pure.lisp
@@ -1121,3 +1121,12 @@
        :allow-warnings t)
     (assert (and fail warn))
     (assert (eql (funcall fun) 2))))
+
+(with-test (:name :macro-argument-modification)
+  (assert (nth-value 2
+                     (checked-compile
+                      '(lambda ()
+                        (macrolet ((a (a)
+                                     (delete 2 (list* '- a))))
+                          (a (* 2 3))))
+                      :allow-warnings 'sb-kernel::macro-arg-modified))))

-----------------------------------------------------------------------


hooks/post-receive
-- 
SBCL
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.