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 7b129ac334ec9badaa093aa7512cf5eb2be2b316..b0c09983dea4e9c223246bcbf3f56333762888e6 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 7686d4e7f0cdd84ce74cb8fa29b33cc9729c0a8c..c7e6f0064ef920c6923ac37376d56cbdd6567ef4 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)