Skip to content

Commit

Permalink
[Bug #19862] Skip compiled result of never reachable expression
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Sep 12, 2023
1 parent 19346c2 commit 6e64d43
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
28 changes: 20 additions & 8 deletions compile.c
Expand Up @@ -4154,9 +4154,10 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
}

static int
compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
LABEL *then_label, LABEL *else_label);

#define COMPILE_SINGLE 2
static int
compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
LABEL *then_label, LABEL *else_label)
Expand All @@ -4175,28 +4176,39 @@ compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
return COMPILE_OK;
}
if (!label->refcnt) {
ADD_INSN(seq, cond, putnil);
}
else {
ADD_LABEL(seq, label);
return COMPILE_SINGLE;
}
ADD_LABEL(seq, label);
ADD_SEQ(ret, seq);
return COMPILE_OK;
}

static int
compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
LABEL *then_label, LABEL *else_label)
{
int ok;
DECL_ANCHOR(ignore);

again:
switch (nd_type(cond)) {
case NODE_AND:
CHECK(compile_logical(iseq, ret, cond->nd_1st, NULL, else_label));
CHECK(ok = compile_logical(iseq, ret, cond->nd_1st, NULL, else_label));
cond = cond->nd_2nd;
if (ok == COMPILE_SINGLE) {
INIT_ANCHOR(ignore);
ret = ignore;
then_label = NEW_LABEL(nd_line(cond));
}
goto again;
case NODE_OR:
CHECK(compile_logical(iseq, ret, cond->nd_1st, then_label, NULL));
CHECK(ok = compile_logical(iseq, ret, cond->nd_1st, then_label, NULL));
cond = cond->nd_2nd;
if (ok == COMPILE_SINGLE) {
INIT_ANCHOR(ignore);
ret = ignore;
else_label = NEW_LABEL(nd_line(cond));
}
goto again;
case NODE_LIT: /* NODE_LIT is always true */
case NODE_TRUE:
Expand Down
11 changes: 11 additions & 0 deletions test/ruby/test_iseq.rb
Expand Up @@ -770,4 +770,15 @@ def test_unreachable_syntax_error
assert_syntax_error("false and break", mesg)
assert_syntax_error("if false and break; end", mesg)
end

def test_unreachable_pattern_matching
assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", %w[1])
begin;
if true or {a: 0} in {a:}
p 1
else
p 0
end
end;
end
end

0 comments on commit 6e64d43

Please sign in to comment.