Project

General

Profile

Bug #697

replacing array during sort may make assertion fail

Added by mame (Yusuke Endoh) almost 12 years ago. Updated over 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
Backport:
[ruby-dev:36983]

Description

=begin
遠藤です。

以下のようにすると assert が失敗します。

$ ./ruby -e 'a = [4,3,2,1]; a.sort! {|x,y| a.replace([]); x <=> y }'
ruby: array.c:1755: rb_ary_sort_bang: Assertion `(((void)
((!((!(((VALUE)(tmp) & RUBY_IMMEDIATE_MASK) || !(((VALUE)(tmp) &
~((VALUE)RUBY_Qnil)) != 0)) && (((struct RBasic*)(tmp))->flags &
RUBY_T_MASK) != RUBY_T_NODE)?(((struct
RBasic*)(tmp))->flags&((((VALUE)1)<<(12+2)))):0) || !((!(((VALUE)(tmp)
& RUBY_IMMEDIATE_MASK) || !(((VALUE)(tmp) & ~((VALUE)RUBY_Qnil)) !=
0)) && (((struct RBasic*)(tmp))->flags & RUBY_T_MASK) !=
RUBY_T_NODE)?(((struct
RBasic*)(tmp))->flags&((((VALUE)1)<<(12+1)))):0)) ? 0 : (assert_fail
("!((!(((VALUE)(tmp) & RUBY_IMMEDIATE_MASK) || !(((VALUE)(tmp) &
~((VALUE)RUBY_Qnil)) != 0)) && (((struct RBasic*)(tmp))->flags &
RUBY_T_MASK) != RUBY_T_NODE)?(((struct
RBasic*)(tmp))->flags&((((VALUE)1)<<(12+2)))):0) || !((!(((VALUE)(tmp)
& RUBY_IMMEDIATE_MASK) || !(((VALUE)(tmp) & ~((VALUE)RUBY_Qnil)) !=
0)) && (((struct RBasic*)(tmp))->flags & RUBY_T_MASK) !=
RUBY_T_NODE)?(((struct
RBasic*)(tmp))->flags&((((VALUE)1)<<(12+1)))):0)", "array.c", 1755,
__PRETTY_FUNCTION
), 0))), ((!(((VALUE)(tmp) & RUBY_IMMEDIATE_MASK)
|| !(((VALUE)(tmp) & ~((VALUE)RUBY_Qnil)) != 0)) && (((struct
RBasic*)(tmp))->flags & RUBY_T_MASK) != RUBY_T_NODE)?(((struct
RBasic*)(tmp))->flags&((((VALUE)1)<<(12+1)))):0))' failed.
アボートしました

以下の修正でいいでしょうか。

Index: array.c
===================================================================
--- array.c (revision 20023)
+++ array.c (working copy)
@@ -1751,14 +1751,14 @@
ruby_qsort(RARRAY_PTR(tmp), RARRAY_LEN(tmp), sizeof(VALUE),
rb_block_given_p()?sort_1:sort_2, &data);

  • if (ARY_EMBED_P(ary) || ARY_EMBED_P(tmp)) {
  • if (ARY_EMBED_P(tmp)) { assert(ARY_EMBED_P(tmp)); MEMCPY(RARRAY_PTR(ary), ARY_EMBED_PTR(tmp), VALUE, ARY_EMBED_LEN(tmp)); ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp)); } else {
  • assert(!ARY_EMBED_P(ary)); assert(!ARY_EMBED_P(tmp));
  • if (ARY_EMBED_P(ary)) FL_UNSET_EMBED(ary); if (RARRAY_PTR(ary) != RARRAY_PTR(tmp)) { assert(!ARY_SHARED_P(tmp)); if (ARY_SHARED_P(ary)) {

--
Yusuke ENDOH mame@tsg.ne.jp
=end

#1

Updated by matz (Yukihiro Matsumoto) almost 12 years ago

  • Status changed from Open to Closed

=begin
fixed by r20026
=end

Also available in: Atom PDF