diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb index 4081769a8c05ac..3bac6454395891 100644 --- a/bootstraptest/test_io.rb +++ b/bootstraptest/test_io.rb @@ -1,4 +1,3 @@ -/freebsd/ =~ RUBY_PLATFORM or assert_finish 5, %q{ r, w = IO.pipe t1 = Thread.new { r.sysread(1) } @@ -31,7 +30,6 @@ end }, '[ruby-dev:32566]' -/freebsd/ =~ RUBY_PLATFORM or assert_finish 5, %q{ r, w = IO.pipe Thread.new { @@ -85,7 +83,7 @@ ARGF.set_encoding "foo" } -/(freebsd|mswin)/ =~ RUBY_PLATFORM or +/mswin/ =~ RUBY_PLATFORM or 10.times do assert_normal_exit %q{ at_exit { p :foo } diff --git a/insns.def b/insns.def index 553d1e4b242b06..78ed3245a2230f 100644 --- a/insns.def +++ b/insns.def @@ -438,6 +438,9 @@ intern () (VALUE str) (VALUE sym) +/* This instruction can raise EncodingError, thus can call + * EncodingError#initialize. */ +// attr bool leaf = false; { sym = rb_str_intern(str); } diff --git a/lib/mkmf.rb b/lib/mkmf.rb index d48780bd1f50bb..4fbba8763f9682 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -2763,9 +2763,6 @@ def init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG) if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes' # turn warnings into errors only for bundled extensions. config['warnflags'] = $warnflags.gsub(/(?:\A|\s)-W\Kerror[-=](?!implicit-function-declaration)/, '') - if /icc\z/ =~ config['CC'] - config['warnflags'].gsub!(/(\A|\s)-W(?:division-by-zero|deprecated-declarations)/, '\1') - end RbConfig.expand(rbconfig['warnflags'] = config['warnflags'].dup) config.each do |key, val| RbConfig.expand(rbconfig[key] = val.dup) if /warnflags/ =~ val diff --git a/lib/time.rb b/lib/time.rb index b157e60863354e..776c82c4f7534b 100644 --- a/lib/time.rb +++ b/lib/time.rb @@ -658,7 +658,7 @@ def xmlschema(time) def rfc3339(time) pattern = /\A\s* (-?\d{4})-(\d\d)-(\d\d) - [T\s] + [T ] (\d\d):(\d\d):(\d\d) (\.\d+)? (Z|[+-]\d\d:\d\d) diff --git a/parse.y b/parse.y index fee9970de988bf..416a1bcc917e33 100644 --- a/parse.y +++ b/parse.y @@ -14095,8 +14095,12 @@ reduce_nodes(struct parser_params *p, NODE **body) while (node) { int newline = (int)nd_fl_newline(node); switch (nd_type(node)) { - end: case NODE_NIL: + // Keep an explicit nil in a method's tail (value) position when it + // is on its own line, so it still emits a :line event and records + // line coverage for that line. [Bug #22302] + if (newline) return; + end: *body = 0; return; case NODE_BEGIN: diff --git a/spec/ruby/core/process/setpriority_spec.rb b/spec/ruby/core/process/setpriority_spec.rb index 4d609734294289..e25182ff3cff54 100644 --- a/spec/ruby/core/process/setpriority_spec.rb +++ b/spec/ruby/core/process/setpriority_spec.rb @@ -13,9 +13,9 @@ Process.getpriority(Process::PRIO_PROCESS, 0).should == priority end - # Darwin and FreeBSD don't seem to handle these at all, getting all out of - # whack with either permission errors or just the wrong value - platform_is_not :darwin, :freebsd do + # Darwin doesn't seem to handle these at all, getting all out of whack + # with either permission errors or just the wrong value + platform_is_not :darwin do it "sets the scheduling priority for a specified process group" do priority = Process.getpriority(Process::PRIO_PGRP, 0) diff --git a/spec/ruby/core/process/times_spec.rb b/spec/ruby/core/process/times_spec.rb index a7ffbb79e57976..49f7de8595e283 100644 --- a/spec/ruby/core/process/times_spec.rb +++ b/spec/ruby/core/process/times_spec.rb @@ -5,15 +5,11 @@ Process.times.should.is_a?(Process::Tms) end - # TODO: Intel C Compiler does not work this example - # http://rubyci.s3.amazonaws.com/icc-x64/ruby-master/log/20221013T030005Z.fail.html.gz - unless RbConfig::CONFIG['CC']&.include?("icx") - it "returns current cpu times" do - t = Process.times - user = t.utime + it "returns current cpu times" do + t = Process.times + user = t.utime - 1 until Process.times.utime > user - Process.times.utime.should > user - end + 1 until Process.times.utime > user + Process.times.utime.should > user end end diff --git a/spec/ruby/core/thread/backtrace/location/source_range_spec.rb b/spec/ruby/core/thread/backtrace/location/source_range_spec.rb index b77e1d5503e729..530e12480b766a 100644 --- a/spec/ruby/core/thread/backtrace/location/source_range_spec.rb +++ b/spec/ruby/core/thread/backtrace/location/source_range_spec.rb @@ -371,14 +371,13 @@ class Symbol end RUBY - # Aborts the test process on CRuby's CI with ZJIT - # "interpolated symbol" => [<<-RUBY, :InterpolatedSymbolNode], - # value = Object.new - # def value.to_s - # (+"\\xFF").force_encoding(Encoding::UTF_8) - # end - # %I[$\#{value}$] - # RUBY + "interpolated symbol" => [<<-RUBY, :InterpolatedSymbolNode], + value = Object.new + def value.to_s + (+"\\xFF").force_encoding(Encoding::UTF_8) + end + %I[$\#{value}$] + RUBY }.each_pair do |description, (source, prism_class, frame)| it "returns the precise range for #{description}" do capture_backtrace_location_source_range(source, prism_class, frame: frame || 0) diff --git a/spec/ruby/language/symbol_spec.rb b/spec/ruby/language/symbol_spec.rb index 83ace4bf2b6424..0c431e18cd239e 100644 --- a/spec/ruby/language/symbol_spec.rb +++ b/spec/ruby/language/symbol_spec.rb @@ -96,7 +96,6 @@ %I{a b #{"c"}}.should == [:a, :b, :c] end - quarantine! do # Aborts the test process on CRuby's CI it "raises an EncodingError when an interpolated symbol has invalid bytes" do -> { :"#{(+"\xFF").force_encoding(Encoding::UTF_8)}" @@ -106,7 +105,6 @@ %I[#{(+"\xFF").force_encoding(Encoding::UTF_8)}] }.should.raise(EncodingError, 'invalid symbol in encoding UTF-8 :"\xFF"') end - end ruby_bug "#20280", ""..."3.4" do it "raises an SyntaxError at parse time when Symbol with invalid bytes" do diff --git a/test/.excludes/TestThread.rb b/test/.excludes/TestThread.rb index 63f193e484ee56..92f0034919dd95 100644 --- a/test/.excludes/TestThread.rb +++ b/test/.excludes/TestThread.rb @@ -1,17 +1,5 @@ # frozen_string_literal: false exclude(/_stack_size$/, 'often too expensive') -if /freebsd13/ =~ RUBY_PLATFORM - # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220216T143001Z.fail.html.gz - # - # 1) Error: - # TestThread#test_signal_at_join: - # Timeout::Error: execution of assert_separately expired timeout (120 sec) - # pid 30743 killed by SIGABRT (signal 6) (core dumped) - # | - # - # /usr/home/chkbuild/chkbuild/tmp/build/20220216T143001Z/ruby/test/ruby/test_thread.rb:1390:in `test_signal_at_join' - exclude(:test_signal_at_join, 'gets stuck somewhere') -end if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # to avoid "`failed to allocate memory (NoMemoryError)" error exclude(:test_thread_interrupt_for_killed_thread, 'TODO') diff --git a/test/.excludes/TestThreadQueue.rb b/test/.excludes/TestThreadQueue.rb deleted file mode 100644 index c8231e372ac6e2..00000000000000 --- a/test/.excludes/TestThreadQueue.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false -if /freebsd13/ =~ RUBY_PLATFORM - # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220308T023001Z.fail.html.gz - # - # 1) Failure: - # TestThreadQueue#test_thr_kill [/usr/home/chkbuild/chkbuild/tmp/build/20220308T023001Z/ruby/test/ruby/test_thread_queue.rb:175]: - # only 169/250 done in 60 seconds. - exclude(:test_thr_kill, 'gets stuck somewhere') -end diff --git a/test/coverage/test_coverage.rb b/test/coverage/test_coverage.rb index 4e384d69007b62..6e92ac2f0e8b82 100644 --- a/test/coverage/test_coverage.rb +++ b/test/coverage/test_coverage.rb @@ -489,6 +489,26 @@ def foo(bar) end; end + def test_line_coverage_for_implicit_nil_return + result = { + :lines => [1, 1, nil, nil, 1, 1, 1, nil, nil, nil, 1, 1] + } + assert_coverage(<<~"end;", { lines: true }, result) # Bug #22302 + def a + nil + end + + def b(x) + if x + nil + end + end + + a + b(true) + end; + end + def test_branch_coverage_for_if_statement result = { :branches => { diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb index 79b5fb17d373fc..b1d45c0289bbd9 100644 --- a/test/io/console/test_io_console.rb +++ b/test/io/console/test_io_console.rb @@ -555,15 +555,6 @@ def assert_ctrl(expect, cc, r, w) end def test_intr - # This test fails randomly on FreeBSD 13 - # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220304T163001Z.fail.html.gz - # - # 1) Failure: - # TestIO_Console#test_intr [/usr/home/chkbuild/chkbuild/tmp/build/20220304T163001Z/ruby/test/io/console/test_io_console.rb:387]: - # <"25"> expected but was - # <"-e:12:in `p': \e[1mexecution expired (\e[1;4mTimeout::Error\e[m\e[1m)\e[m">. - omit if host_os?(/freebsd/) - run_pty("#{<<~"begin;"}\n#{<<~'end;'}") do |r, w, _| begin; require 'timeout' diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb index 0040e8d9f00a5e..2e227b797f7fa9 100644 --- a/test/ruby/test_file_exhaustive.rb +++ b/test/ruby/test_file_exhaustive.rb @@ -1466,8 +1466,6 @@ def test_truncate end def test_flock_exclusive - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - timeout = EnvUtil.apply_timeout_scale(1).to_s File.open(regular_file, "r+") do |f| f.flock(File::LOCK_EX) @@ -1497,8 +1495,6 @@ def test_flock_exclusive end def test_flock_shared - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - timeout = EnvUtil.apply_timeout_scale(1).to_s File.open(regular_file, "r+") do |f| f.flock(File::LOCK_SH) diff --git a/test/ruby/test_insns_leaf.rb b/test/ruby/test_insns_leaf.rb index 9c9a4324cbf8c8..1d5b0c7052bbbc 100644 --- a/test/ruby/test_insns_leaf.rb +++ b/test/ruby/test_insns_leaf.rb @@ -43,4 +43,19 @@ def test_insns_leaf assert Namespace.test?(Id.new(1)), "IDS should include 1" assert !Namespace.test?(Id.new(5)), "IDS should not include 5" end + + def test_intern_is_not_leaf + assert_separately([], <<~'RUBY') + class EncodingError + def initialize(...) + $encoding_error_initialize_called = true + super + end + end + + invalid_utf8 = (+"\xFF").force_encoding(Encoding::UTF_8) + assert_raise(EncodingError) { :"#{invalid_utf8}" } + assert $encoding_error_initialize_called + RUBY + end end diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 3ed10d31c6544f..cd3245761546fd 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -3606,8 +3606,6 @@ def test_cross_thread_close_fd end def test_cross_thread_close_stdio - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - assert_separately([], <<-'end;') IO.pipe do |r,w| $stdin.reopen(r) @@ -4302,8 +4300,6 @@ def test_race_gets_and_close end def test_race_closed_stream - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}") begin; bug13158 = '[ruby-core:79262] [Bug #13158]' @@ -4398,8 +4394,6 @@ def lim.to_int; raise "invalid limit"; end end def test_closed_stream_in_rescue - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - assert_separately([], "#{<<-"begin;"}\n#{<<~"end;"}") begin; 10.times do diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 34a2e3033c86e7..cf21d9942835b4 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -1465,10 +1465,6 @@ def rest_parameter(*rest) end def test_splat_long_array - if File.exist?('/etc/os-release') && File.read('/etc/os-release').include?('openSUSE Leap') - # For RubyCI's openSUSE machine http://rubyci.s3.amazonaws.com/opensuseleap/ruby-trunk/recent.html, which tends to die with NoMemoryError here. - omit 'do not exhaust memory on RubyCI openSUSE Leap machine' - end n = 10_000_000 assert_equal n , rest_parameter(*(1..n)).size, '[Feature #10440]' end diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index eed8e97da86cad..9456dadbcb7439 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -889,8 +889,6 @@ def test_loading_fifo_threading_raise end if File.respond_to?(:mkfifo) def test_loading_fifo_threading_success - omit "[Bug #18613]" if /freebsd/=~ RUBY_PLATFORM - Tempfile.create(%w'fifo .rb') {|f| f.close File.unlink(f.path) diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index da0a12f3d0281b..d0182f9a93fef8 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1009,8 +1009,6 @@ def test_backtrace end def test_thread_timer_and_interrupt - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - bug5757 = '[ruby-dev:44985]' pid = nil cmd = 'Signal.trap(:INT, "DEFAULT"); pipe=IO.pipe; Thread.start {Thread.pass until Thread.main.stop?; puts; STDOUT.flush}; pipe[0].read' @@ -1530,10 +1528,6 @@ def test_signal_at_join # opt = {new_pgroup: true} end - if /freebsd/ =~ RUBY_PLATFORM - omit "[Bug #18613]" - end - assert_separately([], "#{<<~"{#"}\n#{<<~'};'}", timeout: 120) {# n = 1000 diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb index 4c2d921e1166dd..ab0793819e28d1 100644 --- a/test/ruby/test_thread_queue.rb +++ b/test/ruby/test_thread_queue.rb @@ -213,8 +213,6 @@ def test_sized_queue_push_non_block end def test_thr_kill - omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM - bug5343 = '[ruby-core:39634]' Dir.mktmpdir {|d| timeout = 120 diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb index 473c3cabcb4d50..7b3d3844767b77 100644 --- a/test/ruby/test_time_tz.rb +++ b/test/ruby/test_time_tz.rb @@ -6,9 +6,9 @@ class TestTimeTZ < Test::Unit::TestCase has_lisbon_tz = true force_tz_test = ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes" case RUBY_PLATFORM - when /darwin|linux/ + when /darwin|linux|freebsd/ force_tz_test = true - when /freebsd|openbsd/ + when /openbsd/ has_lisbon_tz = false force_tz_test = true end diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb index 799588f613e657..b840e92c686850 100644 --- a/test/socket/test_socket.rb +++ b/test/socket/test_socket.rb @@ -574,7 +574,7 @@ def test_closed_read ensure serv_thread.value.close server.close - end unless RUBY_PLATFORM.include?("freebsd") + end def test_connect_timeout host = "127.0.0.1" diff --git a/test/test_time.rb b/test/test_time.rb index 53ac856d974a46..4054bc446f9676 100644 --- a/test/test_time.rb +++ b/test/test_time.rb @@ -607,6 +607,29 @@ def test_huge_precision define_method(test.sub(/xmlschema/, 'rfc3339')) {__send__(sub, :rfc3339)} end + def test_rfc3339_separator + # RFC 3339 section 5.6 defines the separator as "T", and only notes that an + # application may use a space for readability. The other \s characters are + # not permitted, and Time.xmlschema has never accepted any of them. + t = Time.utc(2011, 10, 5, 22, 26, 12) + assert_equal(t, Time.rfc3339("2011-10-05T22:26:12Z")) + assert_equal(t, Time.rfc3339("2011-10-05 22:26:12Z")) + + ["\t", "\n", "\v", "\f", "\r"].each do |sep| + s = "2011-10-05#{sep}22:26:12Z" + e = assert_raise(ArgumentError, "separator #{sep.inspect}") { Time.rfc3339(s) } + assert_match(/invalid rfc3339 format/, e.message, "separator #{sep.inspect}") + end + + # Time.xmlschema keeps rejecting every separator but "T". + assert_equal(t, Time.xmlschema("2011-10-05T22:26:12Z")) + ["\t", "\n", "\v", "\f", "\r", " "].each do |sep| + assert_raise(ArgumentError, "separator #{sep.inspect}") do + Time.xmlschema("2011-10-05#{sep}22:26:12Z") + end + end + end + def test_parse_with_various_object d = Date.new(2010, 10, 28) dt = DateTime.new(2010, 10, 28) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index a1ee87e2f29e9e..44b3dd390d4533 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -10254,8 +10254,8 @@ fn gen_intern( jit: &mut JITState, asm: &mut Assembler, ) -> Option { - // Save the PC and SP because we might allocate - jit_prepare_call_with_gc(jit, asm); + // rb_str_intern can allocate and raise EncodingError. + jit_prepare_non_leaf_call(jit, asm); let str = asm.stack_opnd(0); let sym = asm.ccall(rb_str_intern as *const u8, vec![str]); diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index ad62deba76cac9..043a477c3fea06 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -684,7 +684,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::StringAppend { recv, other, state } => gen_string_append(jit, asm, function, opnd!(recv), opnd!(other), &function.frame_state(*state)), Insn::StringAppendCodepoint { recv, other, state } => gen_string_append_codepoint(jit, asm, function, opnd!(recv), opnd!(other), &function.frame_state(*state)), Insn::StringEqual { left, right } => gen_string_equal(asm, opnd!(left), opnd!(right)), - Insn::StringIntern { val, state } => gen_intern(asm, opnd!(val), &function.frame_state(*state)), + Insn::StringIntern { val, state } => gen_intern(jit, asm, function, opnd!(val), &function.frame_state(*state)), Insn::ToRegexp { opt, values, state } => gen_toregexp(jit, asm, function, *opt, opnds!(values), &function.frame_state(*state)), Insn::Param => unreachable!("block.insns should not have Insn::Param"), Insn::LoadArg { .. } => return Ok(()), // compiled in the LoadArg pre-pass above @@ -1267,8 +1267,9 @@ fn gen_getglobal(jit: &mut JITState, asm: &mut Assembler, function: &Function, i } /// Intern a string -fn gen_intern(asm: &mut Assembler, val: Opnd, state: &FrameState) -> Opnd { - gen_prepare_leaf_call_with_gc(asm, state); +fn gen_intern(jit: &JITState, asm: &mut Assembler, function: &Function, val: Opnd, state: &FrameState) -> Opnd { + // rb_str_intern can allocate and raise EncodingError. + gen_prepare_non_leaf_call(jit, asm, function, state); asm_ccall!(asm, rb_str_intern, val) }