summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--av.c2
-rw-r--r--mg.c4
-rw-r--r--op.c2
-rw-r--r--pad.c2
-rw-r--r--pp_hot.c2
-rw-r--r--sv.h5
6 files changed, 12 insertions, 5 deletions
diff --git a/av.c b/av.c
index df35b1a839..5f9c0921f5 100644
--- a/av.c
+++ b/av.c
@@ -244,7 +244,7 @@ Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
}
else if (AvREIFY(av)
&& (!AvARRAY(av)[key] /* eg. @_ could have freed elts */
- || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
+ || SvIS_FREED(AvARRAY(av)[key]))) {
AvARRAY(av)[key] = &PL_sv_undef; /* 1/2 reify */
goto emptyness;
}
diff --git a/mg.c b/mg.c
index 6d71b218c6..1423df06f0 100644
--- a/mg.c
+++ b/mg.c
@@ -2040,7 +2040,9 @@ Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
SV **svp = AvARRAY(av);
PERL_UNUSED_ARG(sv);
- if (svp) {
+ /* Not sure why the av can get freed ahead of its sv, but somehow it does
+ in ext/B/t/bytecode.t test 15 (involving print <DATA>) */
+ if (svp && !SvIS_FREED(av)) {
SV *const *const last = svp + AvFILLp(av);
while (svp <= last) {
diff --git a/op.c b/op.c
index a3dee91b33..d9cb1d0b65 100644
--- a/op.c
+++ b/op.c
@@ -407,7 +407,7 @@ Perl_op_clear(pTHX_ OP *o)
clear_pmop:
{
HV * const pmstash = PmopSTASH(cPMOPo);
- if (pmstash && SvREFCNT(pmstash)) {
+ if (pmstash && !SvIS_FREED(pmstash)) {
MAGIC * const mg = mg_find((SV*)pmstash, PERL_MAGIC_symtab);
if (mg) {
PMOP *pmop = (PMOP*) mg->mg_obj;
diff --git a/pad.c b/pad.c
index cbc1cb5075..df1b8f4175 100644
--- a/pad.c
+++ b/pad.c
@@ -233,7 +233,7 @@ Perl_pad_undef(pTHX_ CV* cv)
if (!padlist)
return;
- if (!SvREFCNT(CvPADLIST(cv))) /* may be during global destruction */
+ if (SvIS_FREED(padlist)) /* may be during global destruction */
return;
DEBUG_X(PerlIO_printf(Perl_debug_log,
diff --git a/pp_hot.c b/pp_hot.c
index 24af67eb63..813b606b0b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1909,7 +1909,7 @@ PP(pp_iter)
}
}
- if (sv && SvREFCNT(sv) == 0) {
+ if (sv && SvIS_FREED(sv)) {
*itersvp = Nullsv;
Perl_croak(aTHX_ "Use of freed value in iteration");
}
diff --git a/sv.h b/sv.h
index 99cfe5a7b2..f5a3125649 100644
--- a/sv.h
+++ b/sv.h
@@ -185,6 +185,11 @@ perform the upgrade if necessary. See C<svtype>.
#define SVTYPEMASK 0xff
#define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK)
+/* Sadly there are some parts of the core that have pointers to already-freed
+ SV heads, and rely on being able to tell that they are now free. So mark
+ them all by using a consistent macro. */
+#define SvIS_FREED(sv) ((sv)->sv_flags == SVTYPEMASK)
+
#define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
#define SVs_PADSTALE 0x00000100 /* lexical has gone out of scope */