[perl #39012] another REIFY bug
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index 1c2e0af..30b118b 100644 (file)
--- a/sv.c
+++ b/sv.c
  *   lib/utf8.t lib/Unicode/Collate/t/index.t
  * --jhi
  */
-#define ASSERT_UTF8_CACHE(cache) \
+#   define ASSERT_UTF8_CACHE(cache) \
     STMT_START { if (cache) { assert((cache)[0] <= (cache)[1]); \
                              assert((cache)[2] <= (cache)[3]); \
                              assert((cache)[3] <= (cache)[1]);} \
                              } STMT_END
 #else
-#define ASSERT_UTF8_CACHE(cache) NOOP
+#   define ASSERT_UTF8_CACHE(cache) NOOP
 #endif
 
 #ifdef PERL_OLD_COPY_ON_WRITE
@@ -1717,8 +1717,29 @@ Perl_looks_like_number(pTHX_ SV *sv)
     return grok_number(sbegin, len, NULL);
 }
 
+STATIC bool
+S_glob_2number(pTHX_ GV * const gv)
+{
+    const U32 wasfake = SvFLAGS(gv) & SVf_FAKE;
+    SV *const buffer = sv_newmortal();
+
+    /* FAKE globs can get coerced, so need to turn this off temporarily if it
+       is on.  */
+    SvFAKE_off(gv);
+    gv_efullname3(buffer, gv, "*");
+    SvFLAGS(gv) |= wasfake;
+
+    /* We know that all GVs stringify to something that is not-a-number,
+       so no need to test that.  */
+    if (ckWARN(WARN_NUMERIC))
+       not_a_number(buffer);
+    /* We just want something true to return, so that S_sv_2iuv_common
+       can tail call us and return true.  */
+    return TRUE;
+}
+
 STATIC char *
-S_glob_2inpuv(pTHX_ GV *gv, STRLEN *len, bool want_number)
+S_glob_2pv(pTHX_ GV * const gv, STRLEN * const len)
 {
     const U32 wasfake = SvFLAGS(gv) & SVf_FAKE;
     SV *const buffer = sv_newmortal();
@@ -1729,21 +1750,9 @@ S_glob_2inpuv(pTHX_ GV *gv, STRLEN *len, bool want_number)
     gv_efullname3(buffer, gv, "*");
     SvFLAGS(gv) |= wasfake;
 
-    if (want_number) {
-       /* We know that all GVs stringify to something that is not-a-number,
-          so no need to test that.  */
-       if (ckWARN(WARN_NUMERIC))
-           not_a_number(buffer);
-       /* We just want something true to return, so that S_sv_2iuv_common
-          can tail call us and return true.  */
-       return (char *) 1;
-    } else {
-       assert(SvPOK(buffer));
-       if (len) {
-           *len = SvCUR(buffer);
-       }
-       return SvPVX(buffer);
-    }
+    assert(SvPOK(buffer));
+    *len = SvCUR(buffer);
+    return SvPVX(buffer);
 }
 
 /* Actually, ISO C leaves conversion of UV to IV undefined, but
@@ -2054,7 +2063,7 @@ S_sv_2iuv_common(pTHX_ SV *sv) {
                 if ((NV)(SvIVX(sv)) == SvNVX(sv)) {
                     SvIOK_on(sv);
                 } else {
-                   /*EMPTY*/;  /* Integer is imprecise. NOK, IOKp */
+                   NOOP;  /* Integer is imprecise. NOK, IOKp */
                 }
                 /* UV will not work better than IV */
             } else {
@@ -2069,7 +2078,7 @@ S_sv_2iuv_common(pTHX_ SV *sv) {
                     if ((NV)(SvUVX(sv)) == SvNVX(sv)) {
                         SvIOK_on(sv);
                     } else {
-                       /*EMPTY*/;   /* Integer is imprecise. NOK, IOKp, is UV */
+                       NOOP;   /* Integer is imprecise. NOK, IOKp, is UV */
                     }
                 }
                SvIsUV_on(sv);
@@ -2113,9 +2122,8 @@ S_sv_2iuv_common(pTHX_ SV *sv) {
        }
     }
     else  {
-       if (isGV_with_GP(sv)) {
-           return (bool)PTR2IV(glob_2inpuv((GV *)sv, NULL, TRUE));
-       }
+       if (isGV_with_GP(sv))
+           return glob_2number((GV *)sv);
 
        if (!(SvFLAGS(sv) & SVs_PADTMP)) {
            if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
@@ -2465,7 +2473,7 @@ Perl_sv_2nv(pTHX_ register SV *sv)
     }
     else  {
        if (isGV_with_GP(sv)) {
-           glob_2inpuv((GV *)sv, NULL, TRUE);
+           glob_2number((GV *)sv);
            return 0.0;
        }
 
@@ -2801,9 +2809,8 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
 #endif
     }
     else {
-       if (isGV_with_GP(sv)) {
-           return glob_2inpuv((GV *)sv, lp, FALSE);
-       }
+       if (isGV_with_GP(sv))
+           return glob_2pv((GV *)sv, lp);
 
        if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
            report_uninit(sv);
@@ -3287,7 +3294,7 @@ S_glob_assign_ref(pTHX_ SV *dstr, SV *sstr) {
                           it was a const and its value changed. */
                        if (CvCONST(cv) && CvCONST((CV*)sref)
                            && cv_const_sv(cv) == cv_const_sv((CV*)sref)) {
-                           /*EMPTY*/
+                           NOOP;
                            /* They are 2 constant subroutines generated from
                               the same constant. This probably means that
                               they are really the "same" proxy subroutine
@@ -5359,13 +5366,11 @@ Perl_sv_len_utf8(pTHX_ register SV *sv)
 /* Walk forwards to find the byte corresponding to the passed in UTF-8
    offset.  */
 static STRLEN
-S_sv_pos_u2b_forwards(pTHX_ const U8 *const start, const U8 *const send,
+S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send,
                      STRLEN uoffset)
 {
     const U8 *s = start;
 
-    PERL_UNUSED_CONTEXT;
-
     while (s < send && uoffset--)
        s += UTF8SKIP(s);
     if (s > send) {
@@ -5380,7 +5385,7 @@ S_sv_pos_u2b_forwards(pTHX_ const U8 *const start, const U8 *const send,
    whether to walk forwards or backwards to find the byte corresponding to
    the passed in UTF-8 offset.  */
 static STRLEN
-S_sv_pos_u2b_midway(pTHX_ const U8 *const start, const U8 *send,
+S_sv_pos_u2b_midway(const U8 *const start, const U8 *send,
                      STRLEN uoffset, STRLEN uend)
 {
     STRLEN backw = uend - uoffset;
@@ -5388,7 +5393,7 @@ S_sv_pos_u2b_midway(pTHX_ const U8 *const start, const U8 *send,
        /* The assumption is that going forwards is twice the speed of going
           forward (that's where the 2 * backw comes from).
           (The real figure of course depends on the UTF-8 data.)  */
-       return S_sv_pos_u2b_forwards(aTHX_ start, send, uoffset);
+       return sv_pos_u2b_forwards(start, send, uoffset);
     }
 
     while (backw--) {
@@ -5439,12 +5444,12 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start,
                if ((*mgp)->mg_len != -1) {
                    /* And we know the end too.  */
                    boffset = boffset0
-                       + S_sv_pos_u2b_midway(aTHX_ start + boffset0, send,
+                       + sv_pos_u2b_midway(start + boffset0, send,
                                              uoffset - uoffset0,
                                              (*mgp)->mg_len - uoffset0);
                } else {
                    boffset = boffset0
-                       + S_sv_pos_u2b_forwards(aTHX_ start + boffset0,
+                       + sv_pos_u2b_forwards(start + boffset0,
                                                send, uoffset - uoffset0);
                }
            }
@@ -5457,13 +5462,13 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start,
                }
 
                boffset = boffset0
-                   + S_sv_pos_u2b_midway(aTHX_ start + boffset0,
+                   + sv_pos_u2b_midway(start + boffset0,
                                          start + cache[1],
                                          uoffset - uoffset0,
                                          cache[0] - uoffset0);
            } else {
                boffset = boffset0
-                   + S_sv_pos_u2b_midway(aTHX_ start + boffset0,
+                   + sv_pos_u2b_midway(start + boffset0,
                                          start + cache[3],
                                          uoffset - uoffset0,
                                          cache[2] - uoffset0);
@@ -5475,7 +5480,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start,
            /* In fact, offset0 is either 0, or less than offset, so don't
               need to worry about the other possibility.  */
            boffset = boffset0
-               + S_sv_pos_u2b_midway(aTHX_ start + boffset0, send,
+               + sv_pos_u2b_midway(start + boffset0, send,
                                      uoffset - uoffset0,
                                      (*mgp)->mg_len - uoffset0);
            found = TRUE;
@@ -5484,7 +5489,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start,
 
     if (!found || PL_utf8cache < 0) {
        const STRLEN real_boffset
-           = boffset0 + S_sv_pos_u2b_forwards(aTHX_ start + boffset0,
+           = boffset0 + sv_pos_u2b_forwards(start + boffset0,
                                               send, uoffset - uoffset0);
 
        if (found && PL_utf8cache < 0) {
@@ -5539,16 +5544,16 @@ Perl_sv_pos_u2b(pTHX_ register SV *sv, I32* offsetp, I32* lenp)
        STRLEN uoffset = (STRLEN) *offsetp;
        const U8 * const send = start + len;
        MAGIC *mg = NULL;
-       STRLEN boffset = S_sv_pos_u2b_cached(aTHX_ sv, &mg, start, send,
+       const STRLEN boffset = sv_pos_u2b_cached(sv, &mg, start, send,
                                             uoffset, 0, 0);
 
        *offsetp = (I32) boffset;
 
        if (lenp) {
            /* Convert the relative offset to absolute.  */
-           STRLEN uoffset2 = uoffset + (STRLEN) *lenp;
-           STRLEN boffset2
-               = S_sv_pos_u2b_cached(aTHX_ sv, &mg, start, send, uoffset2,
+           const STRLEN uoffset2 = uoffset + (STRLEN) *lenp;
+           const STRLEN boffset2
+               = sv_pos_u2b_cached(sv, &mg, start, send, uoffset2,
                                      uoffset, boffset) - boffset;
 
            *lenp = boffset2;
@@ -6521,7 +6526,7 @@ screamer2:
             *
             * - jik 9/25/96
             */
-           if (!(cnt < sizeof(buf) && PerlIO_eof(fp)))
+           if (!(cnt < (I32)sizeof(buf) && PerlIO_eof(fp)))
                goto screamer2;
        }
 
@@ -9979,7 +9984,7 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
 
            case SVt_PVGV:
                if (GvUNIQUE((GV*)sstr)) {
-                   /*EMPTY*/;   /* Do sharing here, and fall through */
+                   NOOP;   /* Do sharing here, and fall through */
                }
            case SVt_PVIO:
            case SVt_PVFM:
@@ -10090,7 +10095,7 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
                    if (IoDIRP(dstr)) {
                        IoDIRP(dstr)    = dirp_dup(IoDIRP(dstr));
                    } else {
-                       /*EMPTY*/;
+                       NOOP;
                        /* IoDIRP(dstr) is already a copy of IoDIRP(sstr)  */
                    }
                }
@@ -10916,7 +10921,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     SvREFCNT(&PL_sv_no)                = (~(U32)0)/2;
     SvFLAGS(&PL_sv_no)         = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
                                  |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
-    SvPV_set(&PL_sv_no, SAVEPVN(PL_No, 0));
+    SvPV_set(&PL_sv_no, savepvn(PL_No, 0));
     SvCUR_set(&PL_sv_no, 0);
     SvLEN_set(&PL_sv_no, 1);
     SvIV_set(&PL_sv_no, 0);
@@ -10927,7 +10932,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     SvREFCNT(&PL_sv_yes)       = (~(U32)0)/2;
     SvFLAGS(&PL_sv_yes)                = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
                                  |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
-    SvPV_set(&PL_sv_yes, SAVEPVN(PL_Yes, 1));
+    SvPV_set(&PL_sv_yes, savepvn(PL_Yes, 1));
     SvCUR_set(&PL_sv_yes, 1);
     SvLEN_set(&PL_sv_yes, 2);
     SvIV_set(&PL_sv_yes, 1);