aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--string.c3
-rw-r--r--test/ruby/test_string.rb16
2 files changed, 18 insertions, 1 deletions
diff --git a/string.c b/string.c
index 1a1b9fd6ed..df7e81410a 100644
--- a/string.c
+++ b/string.c
@@ -305,7 +305,8 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existi
OBJ_FREEZE_RAW(str);
}
else {
- str = str_new_frozen(rb_cString, str);
+ if (!OBJ_FROZEN(str))
+ str = str_new_frozen(rb_cString, str);
if (STR_SHARED_P(str)) { /* str should not be shared */
/* shared substring */
str_make_independent(str);
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 489eee33dc..529b1be828 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -3187,6 +3187,22 @@ CODE
assert_same(str, -bar, "uminus deduplicates [Feature #13077]")
end
+ def test_uminus_frozen
+ # embedded
+ str1 = ("foobar" * 3).freeze
+ str2 = ("foobar" * 3).freeze
+ assert_not_same str1, str2
+ assert_same str1, -str1
+ assert_same str1, -str2
+
+ # regular
+ str1 = ("foobar" * 4).freeze
+ str2 = ("foobar" * 4).freeze
+ assert_not_same str1, str2
+ assert_same str1, -str1
+ assert_same str1, -str2
+ end
+
def test_uminus_no_freeze_not_bare
str = @cls.new("foo")
assert_instance_of(@cls, -str)