diff options
author | Peter Zhu <peter@peterzhu.ca> | 2023-03-17 10:12:37 -0400 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2023-03-18 09:07:05 -0400 |
commit | cb22d78354e201ca74eba68a8b4edefb593e6754 (patch) | |
tree | d67779338e1182ff6c5a28432bbaabb3dcde758b /shape.c | |
parent | dc28ccbb6dd0921a75ed21e9d5a6c6c05a0deecf (diff) | |
download | ruby-cb22d78354e201ca74eba68a8b4edefb593e6754.tar.gz |
Fix frozen status loss when moving objects
[Bug #19536]
When objects are moved between size pools, their frozen status is lost
in the shape. This will cause the frozen check to be bypassed when there
is an inline cache. For example, the following script should raise a
FrozenError, but doesn't on Ruby 3.2 and master.
class A
def add_ivars
@a = @b = @c = @d = 1
end
def set_a
@a = 10
end
end
a = A.new
a.add_ivars
a.freeze
b = A.new
b.add_ivars
b.set_a # Set the inline cache in set_a
GC.verify_compaction_references(expand_heap: true, toward: :empty)
a.set_a
Diffstat (limited to 'shape.c')
-rw-r--r-- | shape.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -451,6 +451,7 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap switch ((enum shape_type)dest_shape->type) { case SHAPE_IVAR: + case SHAPE_FROZEN: if (!next_shape->edges) { return NULL; } @@ -464,7 +465,6 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap } break; case SHAPE_ROOT: - case SHAPE_FROZEN: case SHAPE_CAPACITY_CHANGE: case SHAPE_INITIAL_CAPACITY: case SHAPE_T_OBJECT: |