Subject: Re: bug#21899: let/ec continuations not distinct under compiler

From: Andy Wingo <[email-masked]>
Date: Fri, 24 Jun 2016 19:13:01 +0200

On Fri 24 Jun 2016 19:00, Zefram <[email-masked]> writes:

> Andy Wingo wrote:
>>  ,opt (let* ((x (list 'a))
>>              (y (list 'a)))
>>         (list x y))
>>  ;; ->
>>  (let* ((x (list 'a)) (y x)) (list x y))
>
> Wow, that's a scary level of wrongitude.

Indeed :/

Fixed in git with this patch:

>From ea352d9e54793783a8272863748ea6d31b3f7295 Mon Sep 17 00:00:00 2001
From: Andy Wingo <[email-masked]>
Date: Fri, 24 Jun 2016 19:03:36 +0200
Subject: [PATCH] Fix bug that exposed `list' invocations to CSE

* module/language/tree-il/effects.scm (make-effects-analyzer):
  Fix analysis for list, cons, make-prompt-tage, and vector; &allocation
  is a `cause' effect.  Fixes #21899.
* test-suite/tests/cse.test ("cse"): Add test case.
---
 module/language/tree-il/effects.scm | 8 ++++----
 test-suite/tests/cse.test           | 9 +++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/module/language/tree-il/effects.scm b/module/language/tree-il/effects.scm
index 1fe4aeb..6db4d47 100644
--- a/module/language/tree-il/effects.scm
+++ b/module/language/tree-il/effects.scm
@@ -278,16 +278,16 @@ of an expression."
           ;; Primitives that allocate memory.
           (($ <application> _ ($ <primitive-ref> _ 'cons) (x y))
            (logior (compute-effects x) (compute-effects y)
-                   &allocation))
+                   (cause &allocation)))
 
           (($ <application> _ ($ <primitive-ref> _ (or 'list 'vector)) args)
-           (logior (accumulate-effects args) &allocation))
+           (logior (accumulate-effects args) (cause &allocation)))
 
           (($ <application> _ ($ <primitive-ref> _ 'make-prompt-tag) ())
-           &allocation)
+           (cause &allocation))
 
           (($ <application> _ ($ <primitive-ref> _ 'make-prompt-tag) (arg))
-           (logior (compute-effects arg) &allocation))
+           (logior (compute-effects arg) (cause &allocation)))
 
           ;; Primitives that are normally effect-free, but which might
           ;; cause type checks, allocate memory, or access mutable
diff --git a/test-suite/tests/cse.test b/test-suite/tests/cse.test
index e0219e8..ca7dbc2 100644
--- a/test-suite/tests/cse.test
+++ b/test-suite/tests/cse.test
@@ -294,6 +294,15 @@
      (apply (primitive cons) (const 1) (const 2) (const 3))
      (const 4)))
 
+  ;; The (list 'a) does not propagate.
+  (pass-if-cse
+   (let* ((x (list 'a))
+          (y (list 'a)))
+     (list x y))
+   (let (x) (_) ((apply (primitive list) (const a)))
+        (let (y) (_) ((apply (primitive list) (const a)))
+             (apply (primitive list) (lexical x _) (lexical y _)))))
+
   (pass-if "http://bugs.gnu.org/12883"
     ;; In 2.0.6, compiling this code would trigger an out-of-bounds
     ;; vlist access in CSE's traversal of its "database".
-- 
2.8.3