PERL_ARGS_ASSERT_SAVE_GP;
- save_pushptrptr(SvREFCNT_inc(gv), GvGP(gv), SAVEt_GP);
+ SSCHECK(4);
+ SSPUSHINT(SvFAKE(gv));
+ SSPUSHPTR(GvGP(gv));
+ SSPUSHPTR(SvREFCNT_inc(gv));
+ SSPUSHINT(SAVEt_GP);
+
+ /* Don't let the localized GV coerce into non-glob, otherwise we would
+ * not be able to restore GP upon leave from context if that happened */
+ SvFAKE_off(gv);
if (empty) {
GP *gp = Perl_newGP(aTHX_ gv);
*(AV**)ptr = MUTABLE_AV(SSPOPPTR);
break;
case SAVEt_GP: /* scalar reference */
- ptr = SSPOPPTR;
gv = MUTABLE_GV(SSPOPPTR);
gp_free(gv);
- GvGP(gv) = (GP*)ptr;
+ GvGP(gv) = (GP*)SSPOPPTR;
+ if (SSPOPINT)
+ SvFAKE_on(gv);
/* putting a method back into circulation ("local")*/
if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvNAME_get(hv))
mro_method_changed_in(hv);
TOPPTR(nss,ix) = pv_dup(c);
break;
case SAVEt_GP: /* scalar reference */
+ gv = (const GV *)POPPTR(ss,ix);
+ TOPPTR(nss,ix) = gv_dup_inc(gv, param);
gp = (GP*)POPPTR(ss,ix);
TOPPTR(nss,ix) = gp = gp_dup(gp, param);
(void)GpREFCNT_inc(gp);
- gv = (const GV *)POPPTR(ss,ix);
- TOPPTR(nss,ix) = gv_dup_inc(gv, param);
- break;
+ TOPINT(nss,ix) = POPINT(ss,ix);
+ break;
case SAVEt_FREEOP:
ptr = POPPTR(ss,ix);
if (ptr && (((OP*)ptr)->op_private & OPpREFCOUNTED)) {
use warnings;
require './test.pl';
-plan( tests => 188 );
+plan( tests => 191 );
# type coersion on assignment
$foo = 'foo';
is(RT72740a::s1(), "RT72740b::s2", "RT72740::s1 parsed correctly");
is(RT72740a::s3(), "RT72740b::s4", "RT72740::s3 parsed correctly");
+# [perl #71686] Globs that are in symbol table can be un-globbed
+$sym = undef;
+$::{fake} = *sym;
+is (eval 'local *::fake = \"chuck"; $fake', 'chuck',
+ "Localized glob didn't coerce into a RV");
+is ($@, '', "Can localize FAKE glob that's present in stash");
+is (scalar $::{fake}, "*main::sym",
+ "Localized FAKE glob's value was correctly restored");
+
__END__
Perl
Rules