bytecode compiler: don't discard set!
that should error
Robby found this bug using the Redex model and random testing.
This commit is contained in:
parent
4128189499
commit
7176fc4253
|
@ -168,4 +168,9 @@
|
|||
(f)))
|
||||
letrec-exn?)
|
||||
|
||||
;; Make sure a useless `set!` isn't discarded early
|
||||
(err/rt-test
|
||||
(letrec ((B (begin (set! B B) 1))) 1)
|
||||
letrec-exn?)
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -994,7 +994,7 @@ static Scheme_Object *do_let_compile (Scheme_Object *form, Scheme_Comp_Env *orig
|
|||
use_box = MALLOC_N_ATOMIC(int, 1);
|
||||
*use_box = -1;
|
||||
} else
|
||||
use_box = 0;
|
||||
use_box = NULL;
|
||||
|
||||
scheme_begin_dup_symbol_check(&r);
|
||||
|
||||
|
@ -1061,6 +1061,7 @@ static Scheme_Object *do_let_compile (Scheme_Object *form, Scheme_Comp_Env *orig
|
|||
var->mode = SCHEME_VAR_MODE_COMPILE;
|
||||
var->compile.use_box = use_box;
|
||||
var->compile.use_position = m;
|
||||
var->compile.keep_assignment = 1;
|
||||
}
|
||||
vars[m-pre_k] = var;
|
||||
frame = scheme_extend_comp_env(frame, names[m], (Scheme_Object *)var, mutate_frame, 0);
|
||||
|
@ -1074,7 +1075,7 @@ static Scheme_Object *do_let_compile (Scheme_Object *form, Scheme_Comp_Env *orig
|
|||
(recursive ? SCHEME_LET_RECURSIVE : 0));
|
||||
|
||||
if (recursive) {
|
||||
int prev_might_invoke = 0;
|
||||
int prev_might_invoke = 0, j;
|
||||
int group_clauses = 0;
|
||||
Scheme_Object *rhs;
|
||||
|
||||
|
@ -1088,6 +1089,10 @@ static Scheme_Object *do_let_compile (Scheme_Object *form, Scheme_Comp_Env *orig
|
|||
rhs_env = scheme_set_comp_env_name(frame, NULL);
|
||||
rhs = compile_expr(rhs, rhs_env, 0);
|
||||
lv->value = rhs;
|
||||
|
||||
for (j = lv->count; j--; ) {
|
||||
lv->vars[j]->compile.keep_assignment = 0;
|
||||
}
|
||||
|
||||
/* Record when this binding doesn't use any or later bindings in
|
||||
the same set. Break bindings into smaller sets based on this
|
||||
|
|
|
@ -705,7 +705,9 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
|||
&& (SCHEME_LOCAL_POS(sb->var) == SCHEME_LOCAL_POS(sb->val)))
|
||||
return 1;
|
||||
else if (SAME_TYPE(scheme_ir_local_type, SCHEME_TYPE(sb->var))
|
||||
&& SAME_OBJ(sb->var, sb->val))
|
||||
&& SAME_OBJ(sb->var, sb->val)
|
||||
&& ((((Scheme_IR_Local *)sb->var)->mode != SCHEME_VAR_MODE_COMPILE)
|
||||
|| !((Scheme_IR_Local *)sb->var)->compile.keep_assignment))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1414,6 +1414,7 @@ typedef struct Scheme_IR_Local
|
|||
/* To detect uses on right-hand sides in `letrec` */
|
||||
int *use_box;
|
||||
int use_position;
|
||||
int keep_assignment; /* don't optimize away an assignment to this variable */
|
||||
} compile;
|
||||
struct {
|
||||
/* Maps the variable into the letrec-check pass's frames: */
|
||||
|
|
Loading…
Reference in New Issue
Block a user