compiler: fix a copy-propagation bug in the letrec checker

The bug could cause reachable code to be replaced with `(void)`.

Closes #2232
This commit is contained in:
Matthew Flatt 2018-08-17 09:54:42 -06:00
parent 1cf6ab7102
commit dde342a198
2 changed files with 15 additions and 0 deletions

View File

@ -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)

View File

@ -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;
}
}
}