Upgrade to Module-Build-0.27_09
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 4080c45..7a93883 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -138,7 +138,7 @@ PP(pp_rv2gv)
            GV * const gv = (GV*) sv_newmortal();
            gv_init(gv, 0, "", 0, 0);
            GvIOp(gv) = (IO *)sv;
-           (void)SvREFCNT_inc(sv);
+           SvREFCNT_inc_void_NN(sv);
            sv = (SV*) gv;
        }
        else if (SvTYPE(sv) != SVt_PVGV)
@@ -322,7 +322,7 @@ PP(pp_pos)
        if (LvTARG(TARG) != sv) {
            if (LvTARG(TARG))
                SvREFCNT_dec(LvTARG(TARG));
-           LvTARG(TARG) = SvREFCNT_inc(sv);
+           LvTARG(TARG) = SvREFCNT_inc_simple(sv);
        }
        PUSHs(TARG);    /* no SvSETMAGIC */
        RETURN;
@@ -489,19 +489,19 @@ S_refto(pTHX_ SV *sv)
        if (!(sv = LvTARG(sv)))
            sv = &PL_sv_undef;
        else
-           (void)SvREFCNT_inc(sv);
+           SvREFCNT_inc_void_NN(sv);
     }
     else if (SvTYPE(sv) == SVt_PVAV) {
        if (!AvREAL((AV*)sv) && AvREIFY((AV*)sv))
            av_reify((AV*)sv);
        SvTEMP_off(sv);
-       (void)SvREFCNT_inc(sv);
+       SvREFCNT_inc_void_NN(sv);
     }
     else if (SvPADTMP(sv) && !IS_PADGV(sv))
         sv = newSVsv(sv);
     else {
        SvTEMP_off(sv);
-       (void)SvREFCNT_inc(sv);
+       SvREFCNT_inc_void_NN(sv);
     }
     rv = sv_newmortal();
     sv_upgrade(rv, SVt_RV);
@@ -639,14 +639,23 @@ PP(pp_study)
        if (SvSCREAM(sv))
            RETPUSHYES;
     }
-    else {
-       if (PL_lastscream) {
-           SvSCREAM_off(PL_lastscream);
-           SvREFCNT_dec(PL_lastscream);
-       }
-       PL_lastscream = SvREFCNT_inc(sv);
+    s = (unsigned char*)(SvPV(sv, len));
+    pos = len;
+    if (pos <= 0 || !SvPOK(sv)) {
+       /* No point in studying a zero length string, and not safe to study
+          anything that doesn't appear to be a simple scalar (and hence might
+          change between now and when the regexp engine runs without our set
+          magic ever running) such as a reference to an object with overloaded
+          stringification.  */
+       RETPUSHNO;
     }
 
+    if (PL_lastscream) {
+       SvSCREAM_off(PL_lastscream);
+       SvREFCNT_dec(PL_lastscream);
+    }
+    PL_lastscream = SvREFCNT_inc_simple(sv);
+
     s = (unsigned char*)(SvPV(sv, len));
     pos = len;
     if (pos <= 0)
@@ -2433,9 +2442,12 @@ PP(pp_i_divide)
       if (value == 0)
          DIE(aTHX_ "Illegal division by zero");
       num = POPi;
-      if (num == IV_MIN && value == -1)
-          DIE(aTHX_ "Integer overflow in division");
-      value = num / value;
+
+      /* avoid FPE_INTOVF on some platforms when num is IV_MIN */
+      if (value == -1)
+          value = - num;
+      else
+          value = num / value;
       PUSHi( value );
       RETURN;
     }
@@ -2450,7 +2462,11 @@ PP(pp_i_modulo_0)
          dPOPTOPiirl;
          if (!right)
               DIE(aTHX_ "Illegal modulus zero");
-         SETi( left % right );
+         /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
+         if (right == -1)
+             SETi( 0 );
+         else
+             SETi( left % right );
          RETURN;
      }
 }
@@ -2467,7 +2483,11 @@ PP(pp_i_modulo_1)
          dPOPTOPiirl;
          if (!right)
               DIE(aTHX_ "Illegal modulus zero");
-         SETi( left % PERL_ABS(right) );
+         /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
+         if (right == -1)
+             SETi( 0 );
+         else
+             SETi( left % PERL_ABS(right) );
          RETURN;
      }
 }
@@ -2508,7 +2528,11 @@ PP(pp_i_modulo)
               }
          }
 #endif
-         SETi( left % right );
+         /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
+         if (right == -1)
+             SETi( 0 );
+         else
+             SETi( left % right );
          RETURN;
      }
 }
@@ -2992,7 +3016,9 @@ PP(pp_substr)
                        Perl_warner(aTHX_ packWARN(WARN_SUBSTR),
                                "Attempt to use reference as lvalue in substr");
                }
-               if (SvOK(sv))           /* is it defined ? */
+               if (isGV_with_GP(sv))
+                   SvPV_force_nolen(sv);
+               else if (SvOK(sv))      /* is it defined ? */
                    (void)SvPOK_only_UTF8(sv);
                else
                    sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
@@ -3009,7 +3035,7 @@ PP(pp_substr)
            if (LvTARG(TARG) != sv) {
                if (LvTARG(TARG))
                    SvREFCNT_dec(LvTARG(TARG));
-               LvTARG(TARG) = SvREFCNT_inc(sv);
+               LvTARG(TARG) = SvREFCNT_inc_simple(sv);
            }
            LvTARGOFF(TARG) = upos;
            LvTARGLEN(TARG) = urem;
@@ -3040,7 +3066,7 @@ PP(pp_vec)
        if (LvTARG(TARG) != src) {
            if (LvTARG(TARG))
                SvREFCNT_dec(LvTARG(TARG));
-           LvTARG(TARG) = SvREFCNT_inc(src);
+           LvTARG(TARG) = SvREFCNT_inc_simple(src);
        }
        LvTARGOFF(TARG) = offset;
        LvTARGLEN(TARG) = size;
@@ -3324,7 +3350,8 @@ PP(pp_ucfirst)
            if (slen > ulen)
                sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
            SvUTF8_on(TARG);
-           SETs(TARG);
+           sv = TARG;
+           SETs(sv);
        }
        else {
            s = (U8*)SvPV_force_nomg(sv, slen);
@@ -3376,7 +3403,8 @@ PP(pp_uc)
        if (!len) {
            SvUTF8_off(TARG);                           /* decontaminate */
            sv_setpvn(TARG, "", 0);
-           SETs(TARG);
+           sv = TARG;
+           SETs(sv);
        }
        else {
            STRLEN min = len + 1;
@@ -3409,7 +3437,8 @@ PP(pp_uc)
            *d = '\0';
            SvUTF8_on(TARG);
            SvCUR_set(TARG, d - (U8*)SvPVX_const(TARG));
-           SETs(TARG);
+           sv = TARG;
+           SETs(sv);
        }
     }
     else {
@@ -3461,7 +3490,8 @@ PP(pp_lc)
        if (!len) {
            SvUTF8_off(TARG);                           /* decontaminate */
            sv_setpvn(TARG, "", 0);
-           SETs(TARG);
+           sv = TARG;
+           SETs(sv);
        }
        else {
            STRLEN min = len + 1;
@@ -3514,7 +3544,8 @@ PP(pp_lc)
            *d = '\0';
            SvUTF8_on(TARG);
            SvCUR_set(TARG, d - (U8*)SvPVX_const(TARG));
-           SETs(TARG);
+           sv = TARG;
+           SETs(sv);
        }
     }
     else {
@@ -4239,7 +4270,8 @@ PP(pp_reverse)
            sv_setsv(TARG, (SP > MARK)
                    ? *SP
                    : (padoff_du = find_rundefsvoffset(),
-                       (padoff_du == NOT_IN_PAD || PAD_COMPNAME_FLAGS(padoff_du) & SVpad_OUR)
+                       (padoff_du == NOT_IN_PAD
+                        || PAD_COMPNAME_FLAGS_isOUR(padoff_du))
                        ? DEFSV : PAD_SVl(padoff_du)));
        up = SvPV_force(TARG, len);
        if (len > 1) {
@@ -4306,7 +4338,7 @@ PP(pp_split)
     const I32 oldsave = PL_savestack_ix;
     I32 make_mortal = 1;
     bool multiline = 0;
-    MAGIC *mg = (MAGIC *) NULL;
+    MAGIC *mg = NULL;
 
 #ifdef DEBUGGING
     Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);