This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
simplify two conditions in pp_iter:
authorDavid Mitchell <davem@iabyn.com>
Sat, 17 Oct 2015 12:24:30 +0000 (13:24 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 09:18:30 +0000 (09:18 +0000)
    -        if (UNLIKELY(SvMAGICAL(av) || AvREIFY(av))) {
    +        if (UNLIKELY(SvRMAGICAL(av))) {

This condition is deciding whether to call av_fetch or cheat and do
sv = AvARRAY(av)[ix].

The magic test is too broad: av_fetch() only handles the specially on
RMG, not all magic.

The AvREIFY condition was originally added by 64138690 in 2001. It was
an attempt to paper over the cracks if function args are deleted, then
iterate over @_, which now contains freed elements. Since pp_iter now
includes a 'freed sv' check itself, there's no need to call into av_fetch
which has a similar check.

This makes a slight functional change - previously if @_ contained a freed
element, av_fetch would silently return NULL; now instead, pp_iter
croaks with "Use of freed value in iteration", the same as it does with
all other cases involving freed elements being iterated over.

pp_hot.c
t/run/fresh_perl.t

index 7b53fb9..8d00f7a 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2727,7 +2727,7 @@ PP(pp_iter)
         )
             goto retno;
 
-        if (UNLIKELY(SvMAGICAL(av) || AvREIFY(av))) {
+        if (UNLIKELY(SvRMAGICAL(av))) {
             SV * const * const svp = av_fetch(av, ix, FALSE);
             sv = svp ? *svp : NULL;
         }
index f148317..4b5f776 100644 (file)
@@ -624,12 +624,13 @@ my @h = 1 .. 10;
 bad(@h);
 sub bad {
    undef @h;
-   print "O";
+   warn "O\n";
    print for @_;
-   print "K";
+   warn "K\n";
 }
 EXPECT
-OK
+O
+Use of freed value in iteration at - line 7.
 ########
 # Bug 20010506.041
 "abcd\x{1234}" =~ /(a)(b[c])(d+)?/i and print "ok\n";