From dde342a198b7febf5632f0f26a4b4bd330b4ca4d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 17 Aug 2018 09:54:42 -0600 Subject: [PATCH] compiler: fix a copy-propagation bug in the letrec checker The bug could cause reachable code to be replaced with `(void)`. Closes #2232 --- pkgs/racket-test-core/tests/racket/letrec.rktl | 8 ++++++++ racket/src/racket/src/letrec_check.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/letrec.rktl b/pkgs/racket-test-core/tests/racket/letrec.rktl index 82fe86bff1..0df5bcf664 100644 --- a/pkgs/racket-test-core/tests/racket/letrec.rktl +++ b/pkgs/racket-test-core/tests/racket/letrec.rktl @@ -159,5 +159,13 @@ ((offsets) (map quad-super-type (list 1)))) offsets))) +(err/rt-test + (let () + (define (wrap x) x) + (letrec ([f (wrap (lambda () (g)))] + [g (let ([g2 (lambda () (letrec ([x x]) x))]) + g2)]) + (f))) + letrec-exn?) (report-errs) diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index 3c811b85e6..45657773de 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -392,6 +392,13 @@ static Scheme_Object *letrec_check_local(Scheme_Object *o, Letrec_Check_Frame *f ls = (Scheme_Object *)make_deferred_expr_closure(o, frame); ls = scheme_make_pair(ls, outer_frame->def[dpos]); outer_frame->def[dpos] = ls; + + /* But if we're trying to propagate to a variable that was + already referenced, we need to treat this one as + referenced, too */ + if ((outer_frame->ref[dpos] & LET_APPLY_USE) + && in_frame->ref) + in_frame->ref[in_position] |= LET_APPLY_USE; } } }