PL_incgv = NULL;
PL_hintgv = NULL;
PL_errgv = NULL;
- PL_argvgv = NULL;
PL_argvoutgv = NULL;
PL_stdingv = NULL;
PL_stderrgv = NULL;
PL_debstash = NULL;
SvREFCNT_dec(PL_envgv);
+ SvREFCNT_dec(PL_argvgv);
SvREFCNT_dec(PL_DBgv);
SvREFCNT_dec(PL_DBline);
SvREFCNT_dec(PL_DBsub);
PL_envgv = NULL;
+ PL_argvgv = NULL;
PL_DBgv = NULL;
PL_DBline = NULL;
PL_DBsub = NULL;
}
}
if ((PL_argvgv = gv_fetchpvs("ARGV", GV_ADD|GV_NOTQUAL, SVt_PVAV))) {
+ SvREFCNT_inc_simple_void_NN(PL_argvgv);
GvMULTI_on(PL_argvgv);
av_clear(GvAVn(PL_argvgv));
for (; argc > 0; argc--,argv++) {
PL_stdingv = gv_dup(proto_perl->Istdingv, param);
PL_stderrgv = gv_dup(proto_perl->Istderrgv, param);
PL_defgv = gv_dup(proto_perl->Idefgv, param);
- PL_argvgv = gv_dup(proto_perl->Iargvgv, param);
+ PL_argvgv = gv_dup_inc(proto_perl->Iargvgv, param);
PL_argvoutgv = gv_dup(proto_perl->Iargvoutgv, param);
PL_argvout_stack = av_dup_inc(proto_perl->Iargvout_stack, param);
BEGIN { require "./test.pl"; }
-plan(tests => 23);
+plan(tests => 24);
my ($devnull, $no_devnull);
unlink "Io_argv3.tmp";
**PROG**
+# This used to fail an assertion.
+# The tricks with *x and $x are to make PL_argvgv point to a freed SV when
+# the readline op does SvREFCNT_inc on it. undef *x clears the scalar slot
+# ++$x vivifies it, reusing the just-deleted GV that PL_argvgv still points
+# to. The BEGIN block ensures it is freed late enough that nothing else
+# has reused it yet.
+is runperl(prog => 'undef *x; delete $::{ARGV}; $x++;'
+ .'eval q-BEGIN{undef *x} readline-; print qq-ok\n-'),
+ "ok\n", 'deleting $::{ARGV}';
+
END {
unlink_all 'Io_argv1.tmp', 'Io_argv1.tmp_bak',
'Io_argv2.tmp', 'Io_argv2.tmp_bak', 'Io_argv3.tmp';