Feature #8953

`str =~ /pattern/` does not call =~ method if (1) str is a String, (2) /pattern/ is a Regexp literal

Added by Goro Fuji over 1 year ago. Updated about 1 year ago.

[ruby-core:57385]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto

Description

The expression a =~ b does not call the =~ method in some cases.
I think it is a bug that results from optimizations.

See the following code for details:

Code that does not work as expected (shows nothing):

$ ruby -e 's = "foo"; class << s; def =~ (rhs); raise "a"; end; end; s =~ /foo/' # does nothing

Code that works as expected (raises errors):

$ ruby -e 's = "foo"; class << s; def =~ (rhs); raise "a"; end; end; s.=~ /foo/' # call =~ as a method
$ ruby -e 's = "foo"; class << s; def =~ (rhs); raise "a"; end; end; s =~ -> { /foo/ }.call' # RHS is not a Regexp literal but a Regexp object
$ ruby -e 's = Objec.new; class << s; def =~ (rhs); raise "a"; end; end; s =~ /foo/' # LHS is not a String

Associated revisions

Revision 43050
Added by Charlie Somerville over 1 year ago

  • insns.def (opt_regexpmatch1): check Regexp#=~ is not defined before
    calling rb_reg_match()

  • test/ruby/test_regexp.rb: add test

  • vm.c (ruby_vm_redefined_flag): change type to short[]

  • vm.c (vm_redefinition_check_flag): return REGEXP_REDEFINED_OP_FLAG if
    klass == rb_cRegexp

  • vm.c (vm_init_redefined_flag): setup BOP flag for Regexp#=~

  • vm_insnhelper.h: add REGEXP_REDEFINED_OP_FLAG

[Bug #8953]

Revision 43050
Added by Charlie Somerville over 1 year ago

  • insns.def (opt_regexpmatch1): check Regexp#=~ is not defined before
    calling rb_reg_match()

  • test/ruby/test_regexp.rb: add test

  • vm.c (ruby_vm_redefined_flag): change type to short[]

  • vm.c (vm_redefinition_check_flag): return REGEXP_REDEFINED_OP_FLAG if
    klass == rb_cRegexp

  • vm.c (vm_init_redefined_flag): setup BOP flag for Regexp#=~

  • vm_insnhelper.h: add REGEXP_REDEFINED_OP_FLAG

[Bug #8953]

Revision 43052
Added by Shota Fukumori over 1 year ago

  • insns.def (opt_regexpmatch2): Check String#=~ hasn't overridden
    before calling rb_reg_match().

  • test/ruby/test_string.rb: Test for above.

  • vm.c (vm_init_redefined_flag): Add BOP flag for String#=~

[Bug #8953]

Revision 43052
Added by Shota Fukumori over 1 year ago

  • insns.def (opt_regexpmatch2): Check String#=~ hasn't overridden
    before calling rb_reg_match().

  • test/ruby/test_string.rb: Test for above.

  • vm.c (vm_init_redefined_flag): Add BOP flag for String#=~

[Bug #8953]

History

#1 Updated by Shota Fukumori over 1 year ago

hm...

ruby -e'class Regexp; def =~(o); true; end; end; p /a/ =~ "b"' #=> nil

#2 Updated by Charlie Somerville over 1 year ago

  • % Done changed from 0 to 100
  • Status changed from Open to Closed

This issue was solved with changeset r43050.
Goro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • insns.def (opt_regexpmatch1): check Regexp#=~ is not defined before
    calling rb_reg_match()

  • test/ruby/test_regexp.rb: add test

  • vm.c (ruby_vm_redefined_flag): change type to short[]

  • vm.c (vm_redefinition_check_flag): return REGEXP_REDEFINED_OP_FLAG if
    klass == rb_cRegexp

  • vm.c (vm_init_redefined_flag): setup BOP flag for Regexp#=~

  • vm_insnhelper.h: add REGEXP_REDEFINED_OP_FLAG

[Bug #8953]

#3 Updated by Shota Fukumori over 1 year ago

  • Status changed from Closed to Open
  • % Done changed from 100 to 50

The problem still exists for opt_regexpmatch1, right?

#4 Updated by Shota Fukumori over 1 year ago

The problem still exists for opt_regexpmatch1, right?

s/opt_regexpmatch1/opt_regexpmatch2/

#5 Updated by Charlie Somerville over 1 year ago

Ah you are right. Thanks for pointing that out sorah.

#6 Updated by Shota Fukumori over 1 year ago

  • Assignee set to Shota Fukumori
  • Status changed from Open to Assigned

Testing my patch on my machine for regexpmatch2

#7 Updated by Shota Fukumori over 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 50 to 100

This issue was solved with changeset r43052.
Goro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • insns.def (opt_regexpmatch2): Check String#=~ hasn't overridden
    before calling rb_reg_match().

  • test/ruby/test_string.rb: Test for above.

  • vm.c (vm_init_redefined_flag): Add BOP flag for String#=~

[Bug #8953]

#8 Updated by Shota Fukumori over 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN to 1.9.3: UNKNOWN, 2.0.0: REQUIRED

Please backport r43050, 43052

#9 Updated by Tomoyuki Chikanaga over 1 year ago

  • Assignee changed from Shota Fukumori to Tomoyuki Chikanaga
  • Status changed from Closed to Assigned
  • Project changed from Ruby trunk to Backport200
  • Tracker changed from Bug to Backport

#10 Updated by Koichi Sasada over 1 year ago

I checked previous behavior.

versions/install-tags_v1_6_5_/bin/ruby
versions/install-tags_v1_6_6_/bin/ruby
versions/install-tags_v1_6_7_/bin/ruby
versions/install-tags_v1_6_8_/bin/ruby
versions/install-tags_v1_8_5_/bin/ruby
versions/install-tags_v1_8_5_113_/bin/ruby
versions/install-tags_v1_8_5_114_/bin/ruby
versions/install-tags_v1_8_5_115_/bin/ruby
versions/install-tags_v1_8_5_11_/bin/ruby
versions/install-tags_v1_8_5_12_/bin/ruby
versions/install-tags_v1_8_5_231_/bin/ruby
versions/install-tags_v1_8_5_2_/bin/ruby
versions/install-tags_v1_8_5_35_/bin/ruby
versions/install-tags_v1_8_5_52_/bin/ruby
versions/install-tags_v1_8_5_preview1_/bin/ruby
versions/install-tags_v1_8_5_preview2_/bin/ruby
versions/install-tags_v1_8_5_preview3_/bin/ruby
versions/install-tags_v1_8_5_preview4_/bin/ruby
versions/install-tags_v1_8_5_preview5_/bin/ruby
versions/install-tags_v1_8_6_/bin/ruby
versions/install-tags_v1_8_6_110_/bin/ruby
versions/install-tags_v1_8_6_111_/bin/ruby
versions/install-tags_v1_8_6_114_/bin/ruby
versions/install-tags_v1_8_6_230_/bin/ruby
versions/install-tags_v1_8_6_286_/bin/ruby
versions/install-tags_v1_8_6_287_/bin/ruby
versions/install-tags_v1_8_6_368_/bin/ruby
versions/install-tags_v1_8_6_369_/bin/ruby
versions/install-tags_v1_8_6_36_/bin/ruby
versions/install-tags_v1_8_6_383_/bin/ruby
versions/install-tags_v1_8_6_388_/bin/ruby
versions/install-tags_v1_8_6_398_/bin/ruby
versions/install-tags_v1_8_6_399_/bin/ruby
versions/install-tags_v1_8_6_420_/bin/ruby
versions/install-tags_v1_8_6_preview1_/bin/ruby
versions/install-tags_v1_8_6_preview2_/bin/ruby
versions/install-tags_v1_8_6_preview3_/bin/ruby
versions/install-tags_v1_8_7_/bin/ruby
versions/install-tags_v1_8_7_160_/bin/ruby
versions/install-tags_v1_8_7_173_/bin/ruby
versions/install-tags_v1_8_7_174_/bin/ruby
versions/install-tags_v1_8_7_17_/bin/ruby
versions/install-tags_v1_8_7_22_/bin/ruby
versions/install-tags_v1_8_7_248_/bin/ruby
versions/install-tags_v1_8_7_249_/bin/ruby
versions/install-tags_v1_8_7_299_/bin/ruby
versions/install-tags_v1_8_7_301_/bin/ruby
versions/install-tags_v1_8_7_302_/bin/ruby
versions/install-tags_v1_8_7_330_/bin/ruby
versions/install-tags_v1_8_7_334_/bin/ruby
versions/install-tags_v1_8_7_352_/bin/ruby
versions/install-tags_v1_8_7_357_/bin/ruby
versions/install-tags_v1_8_7_358_/bin/ruby
versions/install-tags_v1_8_7_369_/bin/ruby
versions/install-tags_v1_8_7_370_/bin/ruby
versions/install-tags_v1_8_7_371_/bin/ruby
versions/install-tags_v1_8_7_373_/bin/ruby
versions/install-tags_v1_8_7_374_/bin/ruby
versions/install-tags_v1_8_7_71_/bin/ruby
versions/install-tags_v1_8_7_72_/bin/ruby
versions/install-tags_v1_8_7_preview1_/bin/ruby
versions/install-tags_v1_8_7_preview2_/bin/ruby
versions/install-tags_v1_8_7_preview3_/bin/ruby
versions/install-tags_v1_8_7_preview4_/bin/ruby
versions/install-tags_v1_9_0_0_/bin/ruby
versions/install-tags_v1_9_0_1_/bin/ruby
versions/install-tags_v1_9_0_2_/bin/ruby
versions/install-tags_v1_9_0_3_/bin/ruby
versions/install-tags_v1_9_0_4_/bin/ruby
versions/install-tags_v1_9_0_5_/bin/ruby
versions/install-tags_v1_9_1_0_/bin/ruby
versions/install-tags_v1_9_1_126_/bin/ruby
versions/install-tags_v1_9_1_127_/bin/ruby
versions/install-tags_v1_9_1_128_/bin/ruby
versions/install-tags_v1_9_1_129_/bin/ruby
versions/install-tags_v1_9_1_243_/bin/ruby
versions/install-tags_v1_9_1_376_/bin/ruby
versions/install-tags_v1_9_1_378_/bin/ruby
versions/install-tags_v1_9_1_429_/bin/ruby
versions/install-tags_v1_9_1_430_/bin/ruby
versions/install-tags_v1_9_1_431_/bin/ruby
versions/install-tags_v1_9_1_preview1_/bin/ruby
versions/install-tags_v1_9_1_preview2_/bin/ruby
versions/install-tags_v1_9_1_rc1_/bin/ruby
versions/install-tags_v1_9_1_rc2_/bin/ruby
versions/install-tags_v1_9_2_0_/bin/ruby
versions/install-tags_v1_9_2_136_/bin/ruby
versions/install-tags_v1_9_2_180_/bin/ruby
versions/install-tags_v1_9_2_290_/bin/ruby
versions/install-tags_v1_9_2_318_/bin/ruby
versions/install-tags_v1_9_2_320_/bin/ruby
versions/install-tags_v1_9_2_preview1_/bin/ruby
versions/install-tags_v1_9_2_preview2_/bin/ruby
versions/install-tags_v1_9_2_preview3_/bin/ruby
versions/install-tags_v1_9_2_rc1_/bin/ruby
versions/install-tags_v1_9_2_rc2_/bin/ruby
versions/install-tags_v1_9_3_0_/bin/ruby
versions/install-tags_v1_9_3_125_/bin/ruby
versions/install-tags_v1_9_3_194_/bin/ruby
versions/install-tags_v1_9_3_195_/bin/ruby
versions/install-tags_v1_9_3_286_/bin/ruby
versions/install-tags_v1_9_3_327_/bin/ruby
versions/install-tags_v1_9_3_360_/bin/ruby
versions/install-tags_v1_9_3_362_/bin/ruby
versions/install-tags_v1_9_3_374_/bin/ruby
versions/install-tags_v1_9_3_385_/bin/ruby
versions/install-tags_v1_9_3_392_/bin/ruby
versions/install-tags_v1_9_3_429_/bin/ruby
versions/install-tags_v1_9_3_448_/bin/ruby
versions/install-tags_v1_9_3_preview1_/bin/ruby
versions/install-tags_v1_9_3_rc1_/bin/ruby
versions/install-tags_v2_0_0_0_/bin/ruby
versions/install-tags_v2_0_0_195_/bin/ruby
versions/install-tags_v2_0_0_247_/bin/ruby
versions/install-tags_v2_0_0_preview1_/bin/ruby
versions/install-tags_v2_0_0_preview2_/bin/ruby
versions/install-tags_v2_0_0_rc1_/bin/ruby
versions/install-tags_v2_0_0_rc2_/bin/ruby

And all of versions ignore the redefinition.
I implemented 1.9 VM as this behaviour because I think it is spec.

Could you ask matz?

#11 Updated by Koichi Sasada over 1 year ago

(2013/09/27 1:13), ko1 (Koichi Sasada) wrote:

And all of versions ignore the redefinition.
I implemented 1.9 VM as this behaviour because I think it is spec.

Could you ask matz?

I have no objection about that.
However, please be more careful to change the behavior.
(this phrase is also for me, of course)

--
// SASADA Koichi at atdot dot net

#12 Updated by Akira Tanaka over 1 year ago

2013/9/27 ko1 (Koichi Sasada) redmine@ruby-lang.org:

Issue #8953 has been updated by ko1 (Koichi Sasada).

And all of versions ignore the redefinition.
I implemented 1.9 VM as this behaviour because I think it is spec.

I also think so.
The spec is one of the reason Ruby can assign named capture to local variable.

% ruby -e '/def(?.*)/ =~ "abcdefghi"; p var'
"ghi"
--
Tanaka Akira

#13 Updated by Tomoyuki Chikanaga over 1 year ago

  • Project changed from Backport200 to Ruby trunk
  • Tracker changed from Backport to Feature
  • Assignee changed from Tomoyuki Chikanaga to Charlie Somerville

#14 Updated by Koichi Sasada over 1 year ago

  • Target version set to 2.1.0
  • Category set to core
  • Assignee changed from Charlie Somerville to Yukihiro Matsumoto

Could you check it?

#15 Updated by Hiroshi SHIBATA about 1 year ago

  • Target version changed from 2.1.0 to current: 2.2.0

Also available in: Atom PDF