diff --git a/compile.c b/compile.c index 717ec0a2cae5ab..27ed42f1f574d4 100644 --- a/compile.c +++ b/compile.c @@ -3222,6 +3222,25 @@ is_frozen_putstring(INSN *insn, VALUE *op) return 0; } +static int +insn_has_label_before(LINK_ELEMENT *elem) +{ + LINK_ELEMENT *prev = elem->prev; + while (prev) { + if (prev->type == ISEQ_ELEMENT_LABEL) { + LABEL *label = (LABEL *)prev; + if (label->refcnt > 0) { + return 1; + } + } + else if (prev->type == ISEQ_ELEMENT_INSN) { + break; + } + prev = prev->prev; + } + return 0; +} + static int optimize_checktype(rb_iseq_t *iseq, INSN *iobj) { @@ -3467,7 +3486,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal if ((end = (INSN *)get_prev_insn(range)) != 0 && is_frozen_putstring(end, &str_end) && (beg = (INSN *)get_prev_insn(end)) != 0 && - is_frozen_putstring(beg, &str_beg)) { + is_frozen_putstring(beg, &str_beg) && + !(insn_has_label_before(&beg->link) || insn_has_label_before(&end->link))) { int excl = FIX2INT(OPERAND_AT(range, 0)); VALUE lit_range = rb_range_new(str_beg, str_end, excl); diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index f875c0ab40c5e4..cdf6a0cea59f2f 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -36,6 +36,7 @@ def test_range_string assert_equal(["a"], ("a" ... "b").to_a) assert_equal(["a", "b"], ("a" .. "b").to_a) assert_equal([*"a".."z", "aa"], ("a"..).take(27)) + assert_equal([*"a".."z"], eval("('a' || 'b')..'z'").to_a) end def test_range_numeric_string