PL_statgv remembers the handle last used by stat, for the sake of -T _
and -B _. If a glob is freed when PL_statgv points to it, PL_statgv
is set to null.
gv_try_downgrade exists to remove globs and subs that were (possibly
temporarily) vivified by bareword lookup. It is called whenever a
gvop is freed and its gv looks like a candidate for downgrading. That
means it applies, not only to potential sub calls, but also to *foo
and *bar. gv_try_downgrade may delete a glob from the stash alto-
gether if it is empty. So eval "*foo if 0" may delete the *foo glob.
If PL_statgv is pointing to *foo, then eval "*foo if 0" may change the
behaviour, which is not supposed to happen:
$ ./perl -Ilib -le 'stat *{"foo"}; -T _; print $!; -T _; print $!'
Bad file descriptor
Bad file descriptor
$ ./perl -Ilib -le 'stat *{"foo"}; -T _; print $!; eval "*foo if 0"; -T _; print $!'
Bad file descriptor
No such file or directory
!GvSV(gv) && !GvAV(gv) && !GvHV(gv) && !GvIOp(gv) && !GvFORM(gv) &&
GvEGVx(gv) == gv && (stash = GvSTASH(gv))))
return;
+ if (gv == PL_statgv) return;
if (SvMAGICAL(gv)) {
MAGIC *mg;
/* only backref magic is allowed */
use warnings;
-plan( tests => 254 );
+plan( tests => 255 );
# type coercion on assignment
$foo = 'foo';
'constants w/nulls in their names point 2 the right GVs when promoted';
}
+{
+ no warnings 'io';
+ stat *{"try_downgrade"};
+ -T _;
+ $bang = $!;
+ eval "*try_downgrade if 0";
+ -T _;
+ is "$!",$bang,
+ 'try_downgrade does not touch PL_statgv (last stat handle)';
+}
+
# Look away, please.
# This violates perl's internal structures by fiddling with stashes in a
# way that should never happen, but perl should not start trying to free