Project

General

Profile

Actions

Bug #697

closed

replacing array during sort may make assertion fail

Added by mame (Yusuke Endoh) over 15 years ago. Updated almost 13 years ago.

Status:
Closed
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
=end

Actions #1

Updated by matz (Yukihiro Matsumoto) over 15 years ago

  • Status changed from Open to Closed

=begin
fixed by r20026
=end

Actions

Also available in: Atom PDF

Like0
Like0