ensure SVs_PADTMP and SVs_PADTMP not both on
authorDavid Mitchell <davem@iabyn.com>
Fri, 15 Jul 2011 13:46:46 +0000 (14:46 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 15 Jul 2011 13:50:32 +0000 (14:50 +0100)
There's no reason for these two flags to ever both be on.
Fix the one place that was doing this, and assert that this never happens.

If this doesn't break anything, it opens the door to freeing a bit in
SvFLAGS. (woo hoo!)

op.c
sv.h

diff --git a/op.c b/op.c
index 7b129ac..b0c0998 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9458,8 +9458,10 @@ Perl_rpeep(pTHX_ register OP *o)
             * for reference counts, sv_upgrade() etc. */
            if (cSVOP->op_sv) {
                const PADOFFSET ix = pad_alloc(OP_CONST, SVs_PADTMP);
-               if (o->op_type != OP_METHOD_NAMED && SvPADTMP(cSVOPo->op_sv)) {
-                   /* If op_sv is already a PADTMP then it is being used by
+               if (o->op_type != OP_METHOD_NAMED &&
+                   (SvPADTMP(cSVOPo->op_sv) || SvPADMY(cSVOPo->op_sv)))
+               {
+                   /* If op_sv is already a PADTMP/MY then it is being used by
                     * some pad, so make a copy. */
                    sv_setsv(PAD_SVl(ix),cSVOPo->op_sv);
                    SvREADONLY_on(PAD_SVl(ix));
diff --git a/sv.h b/sv.h
index 7686d4e..c7e6f00 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -905,15 +905,34 @@ the scalar's value cannot change unless written to.
 #define SvTHINKFIRST(sv)       (SvFLAGS(sv) & SVf_THINKFIRST)
 
 #define SvPADSTALE(sv)         (SvFLAGS(sv) & SVs_PADSTALE)
-#define SvPADSTALE_on(sv)      (SvFLAGS(sv) |= SVs_PADSTALE)
 #define SvPADSTALE_off(sv)     (SvFLAGS(sv) &= ~SVs_PADSTALE)
 
 #define SvPADTMP(sv)           (SvFLAGS(sv) & SVs_PADTMP)
-#define SvPADTMP_on(sv)                (SvFLAGS(sv) |= SVs_PADTMP)
 #define SvPADTMP_off(sv)       (SvFLAGS(sv) &= ~SVs_PADTMP)
 
 #define SvPADMY(sv)            (SvFLAGS(sv) & SVs_PADMY)
-#define SvPADMY_on(sv)         (SvFLAGS(sv) |= SVs_PADMY)
+
+#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define SvPADTMP_on(sv)      ({                                      \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(!(SvFLAGS(_svpad) & (SVs_PADMY|SVs_PADSTALE)));      \
+           (SvFLAGS(_svpad) |= SVs_PADTMP);            \
+       })
+#  define SvPADMY_on(sv)       ({                                      \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(!(SvFLAGS(_svpad) & SVs_PADTMP));    \
+           (SvFLAGS(_svpad) |= SVs_PADMY);             \
+       })
+#  define SvPADSTALE_on(sv)    ({                                      \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(!(SvFLAGS(_svpad) & SVs_PADTMP));    \
+           (SvFLAGS(_svpad) |= SVs_PADSTALE);          \
+       })
+#else
+#  define SvPADTMP_on(sv)      (SvFLAGS(sv) |= SVs_PADTMP)
+#  define SvPADMY_on(sv)       (SvFLAGS(sv) |= SVs_PADMY)
+#  define SvPADSTALE_on(sv)    (SvFLAGS(sv) |= SVs_PADSTALE)
+#endif
 
 #define SvTEMP(sv)             (SvFLAGS(sv) & SVs_TEMP)
 #define SvTEMP_on(sv)          (SvFLAGS(sv) |= SVs_TEMP)