summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--av.c1
-rw-r--r--pp_ctl.c12
-rwxr-xr-xt/op/goto.t15
3 files changed, 22 insertions, 6 deletions
diff --git a/av.c b/av.c
index af463cb3aa..5242ffc887 100644
--- a/av.c
+++ b/av.c
@@ -41,6 +41,7 @@ av_reify(AV *av)
key = AvARRAY(av) - AvALLOC(av);
while (key)
AvALLOC(av)[--key] = &PL_sv_undef;
+ AvREIFY_off(av);
AvREAL_on(av);
}
diff --git a/pp_ctl.c b/pp_ctl.c
index c882e9ed66..04efce653b 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1873,6 +1873,7 @@ PP(pp_goto)
SV** mark;
I32 items = 0;
I32 oldsave;
+ int arg_was_real = 0;
retry:
if (!CvROOT(cv) && !CvXSUB(cv)) {
@@ -1917,7 +1918,10 @@ PP(pp_goto)
SvREFCNT_dec(GvAV(PL_defgv));
GvAV(PL_defgv) = cx->blk_sub.savearray;
#endif /* USE_THREADS */
- AvREAL_off(av);
+ if (AvREAL(av)) {
+ arg_was_real = 1;
+ AvREAL_off(av); /* so av_clear() won't clobber elts */
+ }
av_clear(av);
}
else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */
@@ -2073,7 +2077,11 @@ PP(pp_goto)
}
Copy(mark,AvARRAY(av),items,SV*);
AvFILLp(av) = items - 1;
-
+ /* preserve @_ nature */
+ if (arg_was_real) {
+ AvREIFY_off(av);
+ AvREAL_on(av);
+ }
while (items--) {
if (*mark)
SvTEMP_off(*mark);
diff --git a/t/op/goto.t b/t/op/goto.t
index 1b34acda39..a62c89925b 100755
--- a/t/op/goto.t
+++ b/t/op/goto.t
@@ -1,10 +1,8 @@
#!./perl
-# $RCSfile: goto.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:56 $
-
# "This IS structured code. It's just randomly structured."
-print "1..9\n";
+print "1..12\n";
while ($?) {
$foo = 1;
@@ -56,7 +54,7 @@ sub bar {
exit;
FINALE:
-print "ok 9\n";
+print "ok 12\n";
exit;
bypass:
@@ -86,5 +84,14 @@ $wherever = NOWHERE;
eval { goto $wherever };
print $@ =~ /Can't find label NOWHERE/ ? "ok 8\n" : "not ok 8\n";
+# see if a modified @_ propagates
+{
+ package Foo;
+ sub DESTROY { my $s = shift; print "ok $s->[0]\n"; }
+ sub show { print "# @_\nnot ok $_[0][0]\n" if @_ != 5; }
+ sub start { push @_, 1, "foo", {}; goto &show; }
+ for (9..11) { start(bless([$_]), 'bar'); }
+}
+
$wherever = FINALE;
goto $wherever;