From 31101c57db2cd076b56d1d7d6c1637e98d951bb6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 23 Apr 2019 17:41:16 -0600 Subject: [PATCH] bytecode compiler: fix coordinate problem in letrec check Example provided by Jay --- .../tests/racket/optimize.rktl | 27 +++++++++++++++++++ racket/src/racket/src/letrec_check.c | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index ea0fd3dde8..9495f762b3 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -6430,4 +6430,31 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(module regression-for-letrec-check-non-app-tracking racket/base + (require racket/match) + + (define (j-emit j) + (struct :ec (x defs) #:transparent) + (struct :def (x e) #:transparent) + (define (e->c^ j) '(1 2 3)) + (define (es->c^ js) + (define n (gensym)) + (match js + ['() (e->c '(:con 'void))] + [(cons a d) + (match-define (:ec ax adefs) (e->c a)) + (match-define (:ec dx ddefs) (es->c d)) + (:ec n (list* (:def n 9) + (append ddefs adefs)))])) + + (define ((make-e->c e->c^) j) + (match-define (and r (:ec n defs)) (e->c^ j)) + r) + (define e->c (make-e->c e->c^)) + (define es->c (make-e->c es->c^)) + + 6)) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (report-errs) diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index c7620a235d..ff667c345d 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -312,15 +312,15 @@ static void letrec_check_lets_resume(Letrec_Check_Frame *frame, Scheme_IR_Let_He that we have invalidated; i.e., adding check-undefineds around references means there is one (more) instance where the LHS variable is not used in application position */ - k = head->count; + k = 0; for (i = head->num_clauses; i--;) { irlv = (Scheme_IR_Let_Value *) body; - k -= irlv->count; for (j = 0; j < irlv->count; j++) { was_checked = (frame->ref[k + j] & LET_CHECKED); if (was_checked) irlv->vars[j]->non_app_count = irlv->vars[j]->use_count; } + k += irlv->count; body = irlv->body; } }