This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make goto &CORE::sub use the right lexical scope
authorFather Chrysostomos <sprout@cpan.org>
Sat, 17 Sep 2011 01:54:57 +0000 (18:54 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 17 Sep 2011 01:54:57 +0000 (18:54 -0700)
Since goto &foo is supposed to replace the current sub call, as though
foo had been called instead, logically foo should see the same lexical
hints that would have been seen if it had been called to begin with.

Regular Perl subs begin with nextstate ops, so they have their own
lexical scopes, but CORE:: subs see the caller’s PL_curcop.  They lack
a nextstate precisely so that they run in the caller’s scope, just as
though a built-in function had been called.

For Perl subs (as opposed to XSUBs), goto-&sub was not reset-
ting PL_curcop to the caller’s value, but leaving as it was, so
goto &CORE::sub would cause the CORE sub to run with the lexical hints
of the subroutine in replaced, instead of that sub’s caller.

This was never a problem until CORE subs came along, as they look like
Perl subs to the internals (they have an op tree and are flagged as
such), but comprise a sequence of ops that can never result from com-
piling Perl source code.

The simple one-line fix is to set PL_curcop in pp_goto for Perl subs
as well as XSUBs.  (For XSUBs it is implied by POPBLOCK.)

pod/perldelta.pod
pp_ctl.c
t/op/coresubs.t

index 8b09500..7b79df8 100644 (file)
@@ -809,6 +809,15 @@ variable [perl #98662].
 
 C<++> and C<--> now work on copies of globs, instead of dying.
 
+=item *
+
+The subroutines in the CORE:: namespace that were introduced in the
+previous development release run with the lexical hints (strict, warnings)
+of the caller, just as though the built-in function had been called.  But
+this was not the case for C<goto &CORE::sub>.  The CORE sub would end up
+running with the lexical hints of the subroutine it replaced, instead of
+that subroutine's caller.  This has been fixed.
+
 =back
 
 =head1 Known Problems
index e8907b6..603d0a5 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2908,6 +2908,7 @@ PP(pp_goto)
                }
                cx->blk_sub.cv = cv;
                cx->blk_sub.olddepth = CvDEPTH(cv);
+               PL_curcop = cx->blk_oldcop;
 
                CvDEPTH(cv)++;
                if (CvDEPTH(cv) < 2)
index f0ebe8e..b3dd3ce 100644 (file)
@@ -108,6 +108,13 @@ while(<$kh>) {
   }
 }
 
+$tests++;
+# This subroutine is outside the warnings scope:
+sub foo { goto &CORE::abs }
+use warnings;
+$SIG{__WARN__} = sub { like shift, qr\^Use of uninitialized\ };
+foo(undef);
+
 is curr_test, $tests+1, 'right number of tests';
 done_testing;