compatibility fix: magic non-propagation in foreach implicit localization
Gurusamy Sarathy [Thu, 11 Feb 1999 05:00:55 +0000 (05:00 +0000)]
p4raw-id: //depot/perl@2854

pp_ctl.c
t/op/local.t
win32/config.gc

index 230d941..e0b65e3 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1640,8 +1640,12 @@ PP(pp_enteriter)
     SAVETMPS;
 
 #ifdef USE_THREADS
-    if (PL_op->op_flags & OPf_SPECIAL)
-       svp = save_threadsv(PL_op->op_targ);    /* per-thread variable */
+    if (PL_op->op_flags & OPf_SPECIAL) {
+       dTHR;
+       svp = &THREADSV(PL_op->op_targ);        /* per-thread variable */
+       SAVEGENERICSV(*svp);
+       *svp = NEWSV(0,0);
+    }
     else
 #endif /* USE_THREADS */
     if (PL_op->op_targ) {
@@ -1649,9 +1653,9 @@ PP(pp_enteriter)
        SAVESPTR(*svp);
     }
     else {
-       GV *gv = (GV*)POPs;
-       (void)save_scalar(gv);
-       svp = &GvSV(gv);                        /* symbol table variable */
+       svp = &GvSV((GV*)POPs);                 /* symbol table variable */
+       SAVEGENERICSV(*svp);
+       *svp = NEWSV(0,0);
     }
 
     ENTER;
index 2f674d1..b478e01 100755 (executable)
@@ -1,8 +1,6 @@
 #!./perl
 
-# $RCSfile: local.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:04 $
-
-print "1..58\n";
+print "1..69\n";
 
 # XXX known to leak scalars
 $ENV{PERL_DESTRUCT_LEVEL} = 0 unless $ENV{PERL_DESTRUCT_LEVEL} > 3;
@@ -198,3 +196,42 @@ print +($ENV{_X_} eq 'a') ? "" : "not ", "ok 56\n";
 print +($ENV{_Y_} eq 'b') ? "" : "not ", "ok 57\n";
 print +($ENV{_Z_} eq 'c') ? "" : "not ", "ok 58\n";
 
+# does implicit localization in foreach skip magic?
+
+$_ = "ok 59,ok 60,";
+my $iter = 0;
+while (/(o.+?),/gc) {
+    print "$1\n";
+    foreach (1..1) { $iter++ }
+    if ($iter > 2) { print "not ok 60\n"; last; }
+}
+
+{
+    package UnderScore;
+    sub TIESCALAR { bless \my $self, shift }
+    sub FETCH { die "read  \$_ forbidden" }
+    sub STORE { die "write \$_ forbidden" }
+    tie $_, __PACKAGE__;
+    my $t = 61;
+    my @tests = (
+       "Nesting"     => sub { print '#'; for (1..3) { print }
+                              print "\n" },                    1,
+       "Reading"     => sub { print },                         0,
+       "Matching"    => sub { $x = /badness/ },                0,
+       "Concat"      => sub { $_ .= "a" },                     0,
+       "Chop"        => sub { chop },                          0,
+       "Filetest"    => sub { -x },                            0,
+       "Assignment"  => sub { $_ = "Bad" },                    0,
+       # XXX whether next one should fail is debatable
+       "Local \$_"   => sub { local $_  = 'ok?'; print },      0,
+       "for local"   => sub { for("#ok?\n"){ print } },        1,
+    );
+    while ( ($name, $code, $ok) = splice(@tests, 0, 3) ) {
+       print "# Testing $name\n";
+       eval { &$code };
+       print(($ok xor $@) ? "ok $t\n" : "not ok $t\n");
+       ++$t;
+    }
+    untie $_;
+}
+
index 703bf04..745d407 100644 (file)
@@ -546,7 +546,7 @@ shrpenv=''
 shsharp='true'
 sig_name='ZERO NUM01 INT QUIT ILL NUM05 NUM06 NUM07 FPE KILL NUM10 SEGV NUM12 PIPE ALRM TERM NUM16 NUM17 NUM18 NUM19 CHLD BREAK ABRT STOP NUM24 CONT CLD'
 sig_name_init='"ZERO", "NUM01", "INT", "QUIT", "ILL", "NUM05", "NUM06", "NUM07", "FPE", "KILL", "NUM10", "SEGV", "NUM12", "PIPE", "ALRM", "TERM", "NUM16", "NUM17", "NUM18", "NUM19", "CHLD", "BREAK", "ABRT", "STOP", "NUM24", "CONT", "CLD", 0'
-sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 20 '
+sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 20 0'
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 20, 0'
 signal_t='void'
 sitearch='~INST_TOP~\site~INST_VER~\lib\~archname~'