}
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;
}
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) {
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;
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,
}
}
- if (sv && SvREFCNT(sv) == 0) {
+ if (sv && SvIS_FREED(sv)) {
*itersvp = Nullsv;
Perl_croak(aTHX_ "Use of freed value in iteration");
}
#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 */