This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #77928] Glob slot assignment and set-magic
authorFather Chrysostomos <sprout@cpan.org>
Tue, 28 Sep 2010 15:47:07 +0000 (08:47 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 28 Sep 2010 18:00:19 +0000 (11:00 -0700)
Stop set-magic from being called after ref-to-glob assignment.

pod/perldelta.pod
sv.h
t/op/gv.t

index cfde5d4..a1430ad 100644 (file)
@@ -624,6 +624,11 @@ function. On other systems, new threads simply do not inherit directory
 handles from their parent threads
 L<[perl #75154]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=75154>.
 
+=item *
+
+Assignment through a glob no longer triggers set-magic on the glob itself
+L<[perl #77928]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=77928>.
+
 =back
 
 =head1 Known Problems
diff --git a/sv.h b/sv.h
index f309d36..be41ac1 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1945,9 +1945,23 @@ Returns a pointer to the character buffer.
                SvSetSV_nosteal_and(dst,src,/*nothing*/;)
 
 #define SvSetMagicSV(dst,src) \
-               SvSetSV_and(dst,src,SvSETMAGIC(dst))
+    SvSetSV_and(dst,src,       \
+       if (SvSMAGICAL(dst)     \
+        && (                    \
+            !isGV_with_GP(dst) || !SvROK(src) || isGV_with_GP(SvRV(src)) \
+           )                                                             \
+          )                                                              \
+           mg_set(dst)                                                   \
+    )
 #define SvSetMagicSV_nosteal(dst,src) \
-               SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst))
+    SvSetSV_nosteal_and(dst,src,       \
+       if (SvSMAGICAL(dst)             \
+        && (                            \
+            !isGV_with_GP(dst) || !SvROK(src) || isGV_with_GP(SvRV(src)) \
+           )                                                             \
+          )                                                              \
+           mg_set(dst)                                                   \
+    )
 
 
 #if !defined(SKIP_DEBUGGING)
index 32afdff..b8363d2 100644 (file)
--- a/t/op/gv.t
+++ b/t/op/gv.t
@@ -12,7 +12,7 @@ BEGIN {
 
 use warnings;
 
-plan( tests => 219 );
+plan( tests => 220 );
 
 # type coersion on assignment
 $foo = 'foo';
@@ -783,6 +783,19 @@ EOF
  }}->($h{k});
 }
 
+# [perl #77928] Glob slot assignment and set-magic
+{
+ package Readonly::Alias;
+ sub TIESCALAR { bless \(my $x = \pop) }
+ sub FETCH { $${$_[0]} }
+ sub STORE { die "Assignment to read-only value" }
+ package main;
+ tie my $alias, "Readonly::Alias", my $var;
+ $var = *bength;
+ # Now modify a glob slot, not the alias itself:
+ ok(scalar eval { *$alias = [] }, 'glob slot assignment skips set-magic');
+}
+
 __END__
 Perl
 Rules