This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_sv_vcatpvfn_flags: simplify wrap checking
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index e2f199f..285b7a6 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -245,7 +245,7 @@ Public API:
        if ((sv)->sv_debug_file) PerlMemShared_free((sv)->sv_debug_file); \
     } STMT_END
 #  define DEBUG_SV_SERIAL(sv)                                              \
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) del_SV\n",    \
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) del_SV\n",    \
            PTR2UV(sv), (long)(sv)->sv_debug_serial))
 #else
 #  define FREE_SV_DEBUG_FILE(sv)
@@ -340,7 +340,7 @@ S_new_SV(pTHX_ const char *file, int line, const char *func)
     sv->sv_debug_serial = PL_sv_serial++;
 
     MEM_LOG_NEW_SV(sv, file, line, func);
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) new_SV (from %s:%d [%s])\n",
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) new_SV (from %s:%d [%s])\n",
            PTR2UV(sv), (long)sv->sv_debug_serial, file, line, func));
 
     return sv;
@@ -392,7 +392,7 @@ S_del_sv(pTHX_ SV *p)
        }
        if (!ok) {
            Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL),
-                            "Attempt to free non-arena SV: 0x%"UVxf
+                            "Attempt to free non-arena SV: 0x%" UVxf
                             pTHX__FORMAT, PTR2UV(p) pTHX__VALUE);
            return;
        }
@@ -654,7 +654,7 @@ do_clean_all(pTHX_ SV *const sv)
        /* don't clean pid table and strtab */
        return;
     }
-    DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%"UVxf"\n", PTR2UV(sv)) ));
+    DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%" UVxf "\n", PTR2UV(sv)) ));
     SvFLAGS(sv) |= SVf_BREAK;
     SvREFCNT_dec_NN(sv);
 }
@@ -1111,7 +1111,7 @@ Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size,
     Newx(adesc->arena, good_arena_size, char);
     adesc->size = good_arena_size;
     adesc->utype = sv_type;
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %"UVuf"\n", 
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %" UVuf "\n",
                          curr, (void*)adesc->arena, (UV)good_arena_size));
 
     start = (char *) adesc->arena;
@@ -1205,7 +1205,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
     const struct body_details *new_type_details;
     const struct body_details *old_type_details
        = bodies_by_type + old_type;
-    SV *referant = NULL;
+    SV *referent = NULL;
 
     PERL_ARGS_ASSERT_SV_UPGRADE;
 
@@ -1270,7 +1270,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
        break;
     case SVt_IV:
        if (SvROK(sv)) {
-           referant = SvRV(sv);
+           referent = SvRV(sv);
            old_type_details = &fake_rv;
            if (new_type == SVt_NV)
                new_type = SVt_PVNV;
@@ -1465,9 +1465,9 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
        if (UNLIKELY(new_type == SVt_REGEXP))
            sv->sv_u.svu_rx = (regexp *)new_body;
        else if (old_type < SVt_PV) {
-           /* referant will be NULL unless the old type was SVt_IV emulating
+           /* referent will be NULL unless the old type was SVt_IV emulating
               SVt_RV */
-           sv->sv_u.svu_rv = referant;
+           sv->sv_u.svu_rv = referent;
        }
        break;
     default:
@@ -1525,6 +1525,11 @@ Perl_sv_backoff(SV *const sv)
     return;
 }
 
+
+/* forward declaration */
+static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags);
+
+
 /*
 =for apidoc sv_grow
 
@@ -1535,7 +1540,6 @@ Use the C<SvGROW> wrapper instead.
 =cut
 */
 
-static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags);
 
 char *
 Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
@@ -1567,15 +1571,11 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
      * to store the COW count. So in general, allocate one more byte than
      * asked for, to make it likely this byte is always spare: and thus
      * make more strings COW-able.
-     * If the new size is a big power of two, don't bother: we assume the
-     * caller wanted a nice 2^N sized block and will be annoyed at getting
-     * 2^N+1.
+     *
      * Only increment if the allocation isn't MEM_SIZE_MAX,
      * otherwise it will wrap to 0.
      */
-    if (   (newlen < 0x1000 || (newlen & (newlen - 1)))
-        && newlen != MEM_SIZE_MAX
-    )
+    if ( newlen != MEM_SIZE_MAX )
         newlen++;
 #endif
 
@@ -1655,6 +1655,7 @@ Perl_sv_setiv(pTHX_ SV *const sv, const IV i)
        /* diag_listed_as: Can't coerce %s to %s in %s */
        Perl_croak(aTHX_ "Can't coerce %s to integer in %s", sv_reftype(sv,0),
                   OP_DESC(PL_op));
+        NOT_REACHED; /* NOTREACHED */
         break;
     default: NOOP;
     }
@@ -1767,6 +1768,7 @@ Perl_sv_setnv(pTHX_ SV *const sv, const NV num)
        /* diag_listed_as: Can't coerce %s to %s in %s */
        Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0),
                   OP_DESC(PL_op));
+        NOT_REACHED; /* NOTREACHED */
         break;
     default: NOOP;
     }
@@ -2042,7 +2044,7 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
     PERL_ARGS_ASSERT_SV_2IUV_NON_PRESERVE;
     PERL_UNUSED_CONTEXT;
 
-    DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_2iuv_non '%s', IV=0x%"UVxf" NV=%"NVgf" inttype=%"UVXf"\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv), (UV)numtype));
+    DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_2iuv_non '%s', IV=0x%" UVxf " NV=%" NVgf " inttype=%" UVXf "\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv), (UV)numtype));
     if (SvNVX(sv) < (NV)IV_MIN) {
        (void)SvIOKp_on(sv);
        (void)SvNOK_on(sv);
@@ -2169,7 +2171,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
                    /* scalar has trailing garbage, eg "42a" */
                }
                DEBUG_c(PerlIO_printf(Perl_debug_log,
-                                     "0x%"UVxf" iv(%"NVgf" => %"IVdf") (precise)\n",
+                                     "0x%" UVxf " iv(%" NVgf " => %" IVdf ") (precise)\n",
                                      PTR2UV(sv),
                                      SvNVX(sv),
                                      SvIVX(sv)));
@@ -2180,7 +2182,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
                   that PV->IV would be better than PV->NV->IV
                   flags already correct - don't set public IOK.  */
                DEBUG_c(PerlIO_printf(Perl_debug_log,
-                                     "0x%"UVxf" iv(%"NVgf" => %"IVdf") (imprecise)\n",
+                                     "0x%" UVxf " iv(%" NVgf " => %" IVdf ") (imprecise)\n",
                                      PTR2UV(sv),
                                      SvNVX(sv),
                                      SvIVX(sv)));
@@ -2211,7 +2213,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
                SvIOK_on(sv);
            SvIsUV_on(sv);
            DEBUG_c(PerlIO_printf(Perl_debug_log,
-                                 "0x%"UVxf" 2iv(%"UVuf" => %"IVdf") (as unsigned)\n",
+                                 "0x%" UVxf " 2iv(%" UVuf " => %" IVdf ") (as unsigned)\n",
                                  PTR2UV(sv),
                                  SvUVX(sv),
                                  SvUVX(sv)));
@@ -2219,7 +2221,24 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
     }
     else if (SvPOKp(sv)) {
        UV value;
-       const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), &value);
+       int numtype;
+        const char *s = SvPVX_const(sv);
+        const STRLEN cur = SvCUR(sv);
+
+        /* short-cut for a single digit string like "1" */
+
+        if (cur == 1) {
+            char c = *s;
+            if (isDIGIT(c)) {
+                if (SvTYPE(sv) < SVt_PVIV)
+                    sv_upgrade(sv, SVt_PVIV);
+                (void)SvIOK_on(sv);
+                SvIV_set(sv, (IV)(c - '0'));
+                return FALSE;
+            }
+        }
+
+       numtype = grok_number(s, cur, &value);
        /* We want to avoid a possible problem when we cache an IV/ a UV which
           may be later translated to an NV, and the resulting NV is not
           the same as the direct translation of the initial string
@@ -2300,7 +2319,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
            if (! numtype && ckWARN(WARN_NUMERIC))
                not_a_number(sv);
 
-           DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2iv(%" NVgf ")\n",
+           DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2iv(%" NVgf ")\n",
                                  PTR2UV(sv), SvNVX(sv)));
 
 #ifdef NV_PRESERVES_UV
@@ -2359,7 +2378,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
                        this NV is in the preserved range, therefore: */
                     if (!(U_V(SvNVX(sv) > 0 ? SvNVX(sv) : -SvNVX(sv))
                           < (UV)IV_MAX)) {
-                        Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
+                        Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%" NVgf " U_V is 0x%" UVxf ", IV_MAX is 0x%" UVxf "\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
                     }
                 } else {
                     /* IN_UV NOT_INT
@@ -2436,8 +2455,8 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags)
     }
 
     if (SvVALID(sv) || isREGEXP(sv)) {
-       /* FBMs use the space for SvIVX and SvNVX for other purposes, and use
-          the same flag bit as SVf_IVisUV, so must not let them cache IVs.
+        /* FBMs use the space for SvIVX and SvNVX for other purposes, so
+           must not let them cache IVs.
           In practice they are extremely unlikely to actually get anywhere
           accessible by user Perl code - the only way that I'm aware of is when
           a constant subroutine which is used as the second argument to index.
@@ -2492,7 +2511,7 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags)
            return 0;
     }
 
-    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2iv(%"IVdf")\n",
+    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2iv(%" IVdf ")\n",
        PTR2UV(sv),SvIVX(sv)));
     return SvIsUV(sv) ? (IV)SvUVX(sv) : SvIVX(sv);
 }
@@ -2575,7 +2594,7 @@ Perl_sv_2uv_flags(pTHX_ SV *const sv, const I32 flags)
            return 0;
     }
 
-    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2uv(%"UVuf")\n",
+    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2uv(%" UVuf ")\n",
                          PTR2UV(sv),SvUVX(sv)));
     return SvIsUV(sv) ? SvUVX(sv) : (UV)SvIVX(sv);
 }
@@ -2656,7 +2675,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
        DEBUG_c({
            STORE_NUMERIC_LOCAL_SET_STANDARD();
            PerlIO_printf(Perl_debug_log,
-                         "0x%"UVxf" num(%" NVgf ")\n",
+                         "0x%" UVxf " num(%" NVgf ")\n",
                          PTR2UV(sv), SvNVX(sv));
            RESTORE_NUMERIC_LOCAL();
        });
@@ -2796,7 +2815,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
     }
     DEBUG_c({
        STORE_NUMERIC_LOCAL_SET_STANDARD();
-       PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2nv(%" NVgf ")\n",
+       PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2nv(%" NVgf ")\n",
                      PTR2UV(sv), SvNVX(sv));
        RESTORE_NUMERIC_LOCAL();
     });
@@ -2902,8 +2921,8 @@ S_infnan_2pv(NV nv, char* buffer, size_t maxlen, char plus) {
       return 0;
     }
     assert((s == buffer + 3) || (s == buffer + 4));
-    *s++ = 0;
-    return s - buffer - 1; /* -1: excluding the zero byte */
+    *s = 0;
+    return s - buffer;
 }
 
 /*
@@ -3166,6 +3185,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
        assert(SvPOK(buffer));
        if (SvUTF8(buffer))
            SvUTF8_on(sv);
+        else
+            SvUTF8_off(sv);
        if (lp)
            *lp = SvCUR(buffer);
        return SvPVX(buffer);
@@ -3193,7 +3214,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            *lp = len;
        SvCUR_set(sv, len);
     }
-    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n",
+    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2pv(%s)\n",
                          PTR2UV(sv),SvPVX_const(sv)));
     if (flags & SV_CONST_RETURN)
        return (char *)SvPVX_const(sv);
@@ -3749,11 +3770,11 @@ Perl_sv_utf8_encode(pTHX_ SV *const sv)
 /*
 =for apidoc sv_utf8_decode
 
-If the PV of the SV is an octet sequence in UTF-8
+If the PV of the SV is an octet sequence in Perl's extended UTF-8
 and contains a multiple-byte character, the C<SvUTF8> flag is turned on
 so that it looks like a character.  If the PV contains only single-byte
 characters, the C<SvUTF8> flag stays off.
-Scans PV for validity and returns false if the PV is invalid UTF-8.
+Scans PV for validity and returns FALSE if the PV is invalid UTF-8.
 
 =cut
 */
@@ -4067,11 +4088,11 @@ Perl_gv_setref(pTHX_ SV *const dstr, SV *const sstr)
                           sv_2mortal(
                              stash
                                ? Perl_newSVpvf(aTHX_
-                                   "%"HEKf"::%"HEKf,
+                                   "%" HEKf "::%" HEKf,
                                    HEKfARG(HvNAME_HEK(stash)),
                                    HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
                                : Perl_newSVpvf(aTHX_
-                                   "%"HEKf,
+                                   "%" HEKf,
                                    HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
                           ),
                           cv,
@@ -4267,12 +4288,17 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
          * special-casing */
         U32 sflags;
         U32 new_dflags;
+        SV *old_rv = NULL;
 
         /* minimal subset of SV_CHECK_THINKFIRST_COW_DROP(dstr) */
         if (SvREADONLY(dstr))
             Perl_croak_no_modify();
-        if (SvROK(dstr))
-            sv_unref_flags(dstr, 0);
+        if (SvROK(dstr)) {
+            if (SvWEAKREF(dstr))
+                sv_unref_flags(dstr, 0);
+            else
+                old_rv = SvRV(dstr);
+        }
 
         assert(!SvGMAGICAL(sstr));
         assert(!SvGMAGICAL(dstr));
@@ -4302,6 +4328,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
             new_dflags = dtype; /* turn off everything except the type */
         }
         SvFLAGS(dstr) = new_dflags;
+        SvREFCNT_dec(old_rv);
 
         return;
     }
@@ -4728,8 +4755,6 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
        }
        if (sflags & SVp_IOK) {
            SvIV_set(dstr, SvIVX(sstr));
-           /* Must do this otherwise some other overloaded use of 0x80000000
-              gets confused. I guess SVpbm_VALID */
            if (sflags & SVf_IVisUV)
                SvIsUV_on(dstr);
        }
@@ -4765,6 +4790,69 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
        SvTAINT(dstr);
 }
 
+
+/*
+=for apidoc sv_set_undef
+
+Equivalent to C<sv_setsv(sv, &PL_sv_undef)>, but more efficient.
+Doesn't handle set magic.
+
+The perl equivalent is C<$sv = undef;>. Note that it doesn't free any string
+buffer, unlike C<undef $sv>.
+
+Introduced in perl 5.25.12.
+
+=cut
+*/
+
+void
+Perl_sv_set_undef(pTHX_ SV *sv)
+{
+    U32 type = SvTYPE(sv);
+
+    PERL_ARGS_ASSERT_SV_SET_UNDEF;
+
+    /* shortcut, NULL, IV, RV */
+
+    if (type <= SVt_IV) {
+        assert(!SvGMAGICAL(sv));
+        if (SvREADONLY(sv)) {
+            /* does undeffing PL_sv_undef count as modifying a read-only
+             * variable? Some XS code does this */
+            if (sv == &PL_sv_undef)
+                return;
+            Perl_croak_no_modify();
+        }
+
+        if (SvROK(sv)) {
+            if (SvWEAKREF(sv))
+                sv_unref_flags(sv, 0);
+            else {
+                SV *rv = SvRV(sv);
+                SvFLAGS(sv) = type; /* quickly turn off all flags */
+                SvREFCNT_dec_NN(rv);
+                return;
+            }
+        }
+        SvFLAGS(sv) = type; /* quickly turn off all flags */
+        return;
+    }
+
+    if (SvIS_FREED(sv))
+        Perl_croak(aTHX_ "panic: attempt to undefine a freed scalar %p",
+            (void *)sv);
+
+    SV_CHECK_THINKFIRST_COW_DROP(sv);
+
+    if (isGV_with_GP(sv))
+        Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
+                       "Undefined value assigned to typeglob");
+    else
+        SvOK_off(sv);
+}
+
+
+
 /*
 =for apidoc sv_setsv_mg
 
@@ -4858,6 +4946,35 @@ Perl_sv_setsv_cow(pTHX_ SV *dstr, SV *sstr)
 #endif
 
 /*
+=for apidoc sv_setpv_bufsize
+
+Sets the SV to be a string of cur bytes length, with at least
+len bytes available. Ensures that there is a null byte at SvEND.
+Returns a char * pointer to the SvPV buffer.
+
+=cut
+*/
+
+char *
+Perl_sv_setpv_bufsize(pTHX_ SV *const sv, const STRLEN cur, const STRLEN len)
+{
+    char *pv;
+
+    PERL_ARGS_ASSERT_SV_SETPV_BUFSIZE;
+
+    SV_CHECK_THINKFIRST_COW_DROP(sv);
+    SvUPGRADE(sv, SVt_PV);
+    pv = SvGROW(sv, len + 1);
+    SvCUR_set(sv, cur);
+    *(SvEND(sv))= '\0';
+    (void)SvPOK_only_UTF8(sv);                /* validate pointer */
+
+    SvTAINT(sv);
+    if (SvTYPE(sv) == SVt_PVCV) CvAUTOLOAD_off(sv);
+    return pv;
+}
+
+/*
 =for apidoc sv_setpvn
 
 Copies a string (possibly containing embedded C<NUL> characters) into an SV.
@@ -4876,6 +4993,8 @@ Perl_sv_setpvn(pTHX_ SV *const sv, const char *const ptr, const STRLEN len)
     PERL_ARGS_ASSERT_SV_SETPVN;
 
     SV_CHECK_THINKFIRST_COW_DROP(sv);
+    if (isGV_with_GP(sv))
+       Perl_croak_no_modify();
     if (!ptr) {
        (void)SvOK_off(sv);
        return;
@@ -5096,28 +5215,6 @@ Perl_sv_usepvn_flags(pTHX_ SV *const sv, char *ptr, const STRLEN len, const U32
        SvSETMAGIC(sv);
 }
 
-/*
-=for apidoc sv_force_normal_flags
-
-Undo various types of fakery on an SV, where fakery means
-"more than" a string: if the PV is a shared string, make
-a private copy; if we're a ref, stop refing; if we're a glob, downgrade to
-an C<xpvmg>; if we're a copy-on-write scalar, this is the on-write time when
-we do the copy, and is also used locally; if this is a
-vstring, drop the vstring magic.  If C<SV_COW_DROP_PV> is set
-then a copy-on-write scalar drops its PV buffer (if any) and becomes
-C<SvPOK_off> rather than making a copy.  (Used where this
-scalar is about to be set to some other value.)  In addition,
-the C<flags> parameter gets passed to C<sv_unref_flags()>
-when unreffing.  C<sv_force_normal> calls this function
-with flags set to 0.
-
-This function is expected to be used to signal to perl that this SV is
-about to be written to, and any extra book-keeping needs to be taken care
-of.  Hence, it croaks on read-only values.
-
-=cut
-*/
 
 static void
 S_sv_uncow(pTHX_ SV * const sv, const U32 flags)
@@ -5197,6 +5294,30 @@ S_sv_uncow(pTHX_ SV * const sv, const U32 flags)
     }
 }
 
+
+/*
+=for apidoc sv_force_normal_flags
+
+Undo various types of fakery on an SV, where fakery means
+"more than" a string: if the PV is a shared string, make
+a private copy; if we're a ref, stop refing; if we're a glob, downgrade to
+an C<xpvmg>; if we're a copy-on-write scalar, this is the on-write time when
+we do the copy, and is also used locally; if this is a
+vstring, drop the vstring magic.  If C<SV_COW_DROP_PV> is set
+then a copy-on-write scalar drops its PV buffer (if any) and becomes
+C<SvPOK_off> rather than making a copy.  (Used where this
+scalar is about to be set to some other value.)  In addition,
+the C<flags> parameter gets passed to C<sv_unref_flags()>
+when unreffing.  C<sv_force_normal> calls this function
+with flags set to 0.
+
+This function is expected to be used to signal to perl that this SV is
+about to be written to, and any extra book-keeping needs to be taken care
+of.  Hence, it croaks on read-only values.
+
+=cut
+*/
+
 void
 Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags)
 {
@@ -5407,7 +5528,7 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c
         sv_utf8_upgrade_flags_grow(dsv, 0, slen + 1);
         dlen = SvCUR(dsv);
       }
-      else SvGROW(dsv, dlen + slen + 1);
+      else SvGROW(dsv, dlen + slen + 3);
       if (sstr == dstr)
        sstr = SvPVX_const(dsv);
       Move(sstr, SvPVX(dsv) + dlen, slen, char);
@@ -5423,7 +5544,7 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c
           bytes *and* utf8, which would indicate a bug elsewhere. */
        assert(sstr != dstr);
 
-       SvGROW(dsv, dlen + slen * 2 + 1);
+       SvGROW(dsv, dlen + slen * 2 + 3);
        d = (U8 *)SvPVX(dsv) + dlen;
 
        while (sstr < send) {
@@ -5615,7 +5736,9 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how,
     */
     if (!obj || obj == sv ||
        how == PERL_MAGIC_arylen ||
-       how == PERL_MAGIC_symtab ||
+        how == PERL_MAGIC_regdata ||
+        how == PERL_MAGIC_regdatum ||
+        how == PERL_MAGIC_symtab ||
        (SvTYPE(obj) == SVt_PVGV &&
            (GvSV(obj) == sv || GvHV(obj) == (const HV *)sv
             || GvAV(obj) == (const AV *)sv || GvCV(obj) == (const CV *)sv
@@ -6183,7 +6306,7 @@ Perl_sv_kill_backrefs(pTHX_ SV *const sv, AV *const av)
 
                } else {
                    Perl_croak(aTHX_
-                              "panic: magic_killbackrefs (flags=%"UVxf")",
+                              "panic: magic_killbackrefs (flags=%" UVxf ")",
                               (UV)SvFLAGS(referrer));
                }
 
@@ -6215,7 +6338,7 @@ C<SvPV_force_flags> that applies to C<bigstr>.
 */
 
 void
-Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *const little, const STRLEN littlelen, const U32 flags)
+Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *little, const STRLEN littlelen, const U32 flags)
 {
     char *big;
     char *mid;
@@ -6228,6 +6351,16 @@ Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN l
 
     SvPV_force_flags(bigstr, curlen, flags);
     (void)SvPOK_only_UTF8(bigstr);
+
+    if (little >= SvPVX(bigstr) &&
+        little < SvPVX(bigstr) + (SvLEN(bigstr) ? SvLEN(bigstr) : SvCUR(bigstr))) {
+        /* little is a pointer to within bigstr, since we can reallocate bigstr,
+           or little...little+littlelen might overlap offset...offset+len we make a copy
+        */
+        little = savepvn(little, littlelen);
+        SAVEFREEPV(little);
+    }
+
     if (offset + len > curlen) {
        SvGROW(bigstr, offset+len+1);
        Zero(SvPVX(bigstr)+curlen, offset+len-curlen, char);
@@ -6517,7 +6650,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                {
                    if (PL_stashcache) {
                        DEBUG_o(Perl_deb(aTHX_
-                           "sv_clear clearing PL_stashcache for '%"HEKf
+                           "sv_clear clearing PL_stashcache for '%" HEKf
                            "'\n",
                             HEKfARG(hek)));
                        (void)hv_deletehek(PL_stashcache,
@@ -6584,7 +6717,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                /* If we're in a stash, we don't own a reference to it.
                 * However it does have a back reference to us, which
                 * needs to be cleared.  */
-               if (!SvVALID(sv) && (stash = GvSTASH(sv)))
+               if ((stash = GvSTASH(sv)))
                        sv_del_backref(MUTABLE_SV(stash), sv);
            }
            /* FIXME. There are probably more unreferenced pointers to SVs
@@ -6741,7 +6874,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
 #ifdef DEBUGGING
            if (SvTEMP(sv)) {
                Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING),
-                        "Attempt to free temp prematurely: SV 0x%"UVxf
+                        "Attempt to free temp prematurely: SV 0x%" UVxf
                         pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE);
                continue;
            }
@@ -6866,7 +6999,7 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
        if (check_refcnt && SvREFCNT(sv)) {
            if (PL_in_clean_objs)
                Perl_croak(aTHX_
-                 "DESTROY created new reference to dead object '%"HEKf"'",
+                 "DESTROY created new reference to dead object '%" HEKf "'",
                   HEKfARG(HvNAME_HEK(stash)));
            /* DESTROY gave object new lease on life */
            return FALSE;
@@ -6937,7 +7070,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc)
 #ifdef DEBUGGING
         if (SvTEMP(sv)) {
             Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING),
-                             "Attempt to free temp prematurely: SV 0x%"UVxf
+                             "Attempt to free temp prematurely: SV 0x%" UVxf
                              pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE);
             return;
         }
@@ -6984,7 +7117,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc)
 #endif
         /* This may not return:  */
         Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
-                    "Attempt to free unreferenced scalar: SV 0x%"UVxf
+                    "Attempt to free unreferenced scalar: SV 0x%" UVxf
                     pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE);
 #endif
     }
@@ -7573,8 +7706,8 @@ Perl_sv_pos_b2u_flags(pTHX_ SV *const sv, STRLEN const offset, U32 flags)
     s = (const U8*)SvPV_flags(sv, blen, flags);
 
     if (blen < offset)
-       Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%"UVuf
-                  ", byte=%"UVuf, (UV)blen, (UV)offset);
+       Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%" UVuf
+                  ", byte=%" UVuf, (UV)blen, (UV)offset);
 
     send = s + offset;
 
@@ -7691,7 +7824,7 @@ S_assert_uft8_cache_coherent(pTHX_ const char *const func, STRLEN from_cache,
        while printing error messages.  */
     SAVEI8(PL_utf8cache);
     PL_utf8cache = 0;
-    Perl_croak(aTHX_ "panic: %s cache %"UVuf" real %"UVuf" for %"SVf,
+    Perl_croak(aTHX_ "panic: %s cache %" UVuf " real %" UVuf " for %" SVf,
               func, (UV) from_cache, (UV) real, SVfARG(sv));
 }
 
@@ -8534,10 +8667,10 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
 
     /* some trace debug output */
     DEBUG_P(PerlIO_printf(Perl_debug_log,
-       "Screamer: entering, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
+       "Screamer: entering, ptr=%" UVuf ", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
     DEBUG_P(PerlIO_printf(Perl_debug_log,
-       "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"
-        UVuf"\n",
+       "Screamer: entering: PerlIO * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%"
+        UVuf "\n",
               PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
               PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0)));
 
@@ -8547,13 +8680,27 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
        if (cnt > 0) {
             /* if there is a separator */
            if (rslen) {
-                /* loop until we hit the end of the read-ahead buffer */
-               while (cnt > 0) {                    /* this     |  eat */
-                    /* scan forward copying and searching for rslast as we go */
-                   cnt--;
-                   if ((*bp++ = *ptr++) == rslast)  /* really   |  dust */
-                       goto thats_all_folks;        /* screams  |  sed :-) */
-               }
+                /* find next rslast */
+                STDCHAR *p;
+
+                /* shortcut common case of blank line */
+                cnt--;
+                if ((*bp++ = *ptr++) == rslast)
+                    goto thats_all_folks;
+
+                p = (STDCHAR *)memchr(ptr, rslast, cnt);
+                if (p) {
+                    SSize_t got = p - ptr + 1;
+                    Copy(ptr, bp, got, STDCHAR);
+                    ptr += got;
+                    bp  += got;
+                    cnt -= got;
+                    goto thats_all_folks;
+                }
+                Copy(ptr, bp, cnt, STDCHAR);
+                ptr += cnt;
+                bp  += cnt;
+                cnt = 0;
            }
            else {
                 /* no separator, slurp the full buffer */
@@ -8583,12 +8730,12 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
         /* we need to refill the read-ahead buffer if possible */
 
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-                            "Screamer: going to getc, ptr=%"UVuf", cnt=%"IVdf"\n",
+                            "Screamer: going to getc, ptr=%" UVuf ", cnt=%" IVdf "\n",
                              PTR2UV(ptr),(IV)cnt));
        PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* deregisterize cnt and ptr */
 
        DEBUG_Pv(PerlIO_printf(Perl_debug_log,
-          "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf"\n",
+          "Screamer: pre: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf "\n",
            PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
            PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
 
@@ -8604,7 +8751,7 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
        i   = PerlIO_getc(fp);          /* get more characters */
 
        DEBUG_Pv(PerlIO_printf(Perl_debug_log,
-          "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf"\n",
+          "Screamer: post: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf "\n",
            PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
            PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
 
@@ -8612,7 +8759,7 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
        cnt = PerlIO_get_cnt(fp);
        ptr = (STDCHAR*)PerlIO_get_ptr(fp);     /* reregisterize cnt and ptr */
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-           "Screamer: after getc, ptr=%"UVuf", cnt=%"IVdf"\n",
+           "Screamer: after getc, ptr=%" UVuf ", cnt=%" IVdf "\n",
            PTR2UV(ptr),(IV)cnt));
 
        if (i == EOF)                   /* all done for ever? */
@@ -8642,10 +8789,10 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
     if (shortbuffered)
        cnt += shortbuffered;
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-            "Screamer: quitting, ptr=%"UVuf", cnt=%"IVdf"\n",PTR2UV(ptr),(IV)cnt));
+            "Screamer: quitting, ptr=%" UVuf ", cnt=%" IVdf "\n",PTR2UV(ptr),(IV)cnt));
     PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* put these back or we're in trouble */
     DEBUG_P(PerlIO_printf(Perl_debug_log,
-       "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf
+       "Screamer: end: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf
        "\n",
        PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
        PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
@@ -8864,7 +9011,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
            /* I don't think we can get here. Maybe I should assert this
               And if we do get here I suspect that sv_setnv will croak. NWC
               Fall through. */
-           DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_inc punt failed to convert '%s' to IOK or NOKp, UV=0x%"UVxf" NV=%"NVgf"\n",
+           DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_inc punt failed to convert '%s' to IOK or NOKp, UV=0x%" UVxf " NV=%" NVgf "\n",
                                  SvPVX_const(sv), SvIVX(sv), SvNVX(sv)));
        }
 #endif /* PERL_PRESERVE_IVUV */
@@ -9042,7 +9189,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv)
            /* I don't think we can get here. Maybe I should assert this
               And if we do get here I suspect that sv_setnv will croak. NWC
               Fall through. */
-           DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_dec punt failed to convert '%s' to IOK or NOKp, UV=0x%"UVxf" NV=%"NVgf"\n",
+           DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_dec punt failed to convert '%s' to IOK or NOKp, UV=0x%" UVxf " NV=%" NVgf "\n",
                                  SvPVX_const(sv), SvIVX(sv), SvNVX(sv)));
        }
     }
@@ -9198,7 +9345,14 @@ SV is set to 1.  If C<len> is zero, Perl will compute the length using
 C<strlen()>, (which means if you use this option, that C<s> can't have embedded
 C<NUL> characters and has to have a terminating C<NUL> byte).
 
-For efficiency, consider using C<newSVpvn> instead.
+This function can cause reliability issues if you are likely to pass in
+empty strings that are not null terminated, because it will run
+strlen on the string and potentially run past valid memory.
+
+Using L</newSVpvn> is a safer alternative for non C<NUL> terminated strings.
+For string literals use L</newSVpvs> instead.  This function will work fine for
+C<NUL> terminated strings, but if you want to avoid the if statement on whether
+to call C<strlen> use C<newSVpvn> instead (calling C<strlen> yourself).
 
 =cut
 */
@@ -9736,7 +9890,7 @@ Perl_sv_2io(pTHX_ SV *const sv)
            gv = MUTABLE_GV(sv);
            io = GvIO(gv);
            if (!io)
-               Perl_croak(aTHX_ "Bad filehandle: %"HEKf,
+               Perl_croak(aTHX_ "Bad filehandle: %" HEKf,
                                     HEKfARG(GvNAME_HEK(gv)));
            break;
        }
@@ -9759,7 +9913,7 @@ Perl_sv_2io(pTHX_ SV *const sv)
                newsv = sv_newmortal();
                sv_setsv_nomg(newsv, sv);
            }
-           Perl_croak(aTHX_ "Bad filehandle: %"SVf, SVfARG(newsv));
+           Perl_croak(aTHX_ "Bad filehandle: %" SVf, SVfARG(newsv));
        }
        break;
     }
@@ -9941,7 +10095,7 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
        if (!SvPOK(sv)) {
            SvPOK_on(sv);               /* validate pointer */
            SvTAINT(sv);
-           DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n",
+           DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2pv(%s)\n",
                                  PTR2UV(sv),SvPVX_const(sv)));
        }
     }
@@ -10075,7 +10229,7 @@ Perl_sv_ref(pTHX_ SV *dst, const SV *const sv, const int ob)
     if (ob && SvOBJECT(sv)) {
        HvNAME_get(SvSTASH(sv))
                     ? sv_sethek(dst, HvNAME_HEK(SvSTASH(sv)))
-                    : sv_setpvn(dst, "__ANON__", 8);
+                    : sv_setpvs(dst, "__ANON__");
     }
     else {
         const char * reftype = sv_reftype(sv, 0);
@@ -10224,7 +10378,7 @@ Perl_sv_setref_pv(pTHX_ SV *const rv, const char *const classname, void *const p
     PERL_ARGS_ASSERT_SV_SETREF_PV;
 
     if (!pv) {
-       sv_setsv(rv, &PL_sv_undef);
+       sv_set_undef(rv);
        SvSETMAGIC(rv);
     }
     else
@@ -10805,7 +10959,7 @@ Perl_sv_vsetpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
 {
     PERL_ARGS_ASSERT_SV_VSETPVFN;
 
-    sv_setpvs(sv, "");
+    SvPVCLEAR(sv);
     sv_vcatpvfn_flags(sv, pat, patlen, args, svargs, svmax, maybe_tainted, 0);
 }
 
@@ -11473,9 +11627,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 #  define FV_ISFINITE(x) Perl_isfinite((NV)(x))
 #endif
         NV nv;
-       STRLEN have;
-       STRLEN need;
-       STRLEN gap;
+       STRLEN float_need; /* what PL_efloatsize needs to become */
        const char *dotstr = ".";
        STRLEN dotstrlen = 1;
        I32 efix = 0; /* explicit format parameter index */
@@ -11748,7 +11900,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                 * vectorize happen normally
                 */
                if (sv_isobject(vecsv) && sv_derived_from(vecsv, "version")) {
-                   if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
+                   if ( hv_existss(MUTABLE_HV(SvRV(vecsv)), "alpha") ) {
                        Perl_ck_warner_d(aTHX_ packWARN(WARN_PRINTF),
                        "vector argument not supported with alpha versions");
                        goto vdblank;
@@ -11872,7 +12024,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            if (vectorize)
                goto unknown;
             if (infnan)
-                Perl_croak(aTHX_ "Cannot printf %"NVgf" with '%c'",
+                Perl_croak(aTHX_ "Cannot printf %" NVgf " with '%c'",
                            /* no va_arg() case */
                            SvNV_nomg(argsv), (int)c);
            uv = (args) ? va_arg(*args, int) : SvIV_nomg(argsv);
@@ -12253,14 +12405,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                 NV_TO_FV(nv, fv);
             }
 
-           need = 0;
+           float_need = 0;
            /* frexp() (or frexpl) has some unspecified behaviour for
              * nan/inf/-inf, so let's avoid calling that on non-finites. */
            if (isALPHA_FOLD_NE(c, 'e') && FV_ISFINITE(fv)) {
                 i = PERL_INT_MIN;
                 (void)Perl_frexp((NV)fv, &i);
                 if (i == PERL_INT_MIN)
-                    Perl_die(aTHX_ "panic: frexp: %"FV_GF, fv);
+                    Perl_die(aTHX_ "panic: frexp: %" FV_GF, fv);
                 /* Do not set hexfp earlier since we want to printf
                  * Inf/NaN for Inf/NaN, not their hexfp. */
                 hexfp = isALPHA_FOLD_EQ(c, 'a');
@@ -12271,7 +12423,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                      * exponent.  Secondly, for the reasonably common
                      * long doubles case, the "80-bit extended", two
                      * or six bytes of the NV are unused. */
-                    need +=
+                    float_need +=
                         (fv < 0) ? 1 : 0 + /* possible unary minus */
                         2 + /* "0x" */
                         1 + /* the very unlikely carry */
@@ -12290,24 +12442,30 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                      * See the definition of DOUBLEDOUBLE_MAXBITS.
                      *
                      * Need 2 hexdigits for each byte. */
-                    need += (DOUBLEDOUBLE_MAXBITS/8 + 1) * 2;
+                    float_need += (DOUBLEDOUBLE_MAXBITS/8 + 1) * 2;
                     /* the size for the exponent already added */
 #endif
 #ifdef USE_LOCALE_NUMERIC
                         STORE_LC_NUMERIC_SET_TO_NEEDED();
                         if (PL_numeric_radix_sv && IN_LC(LC_NUMERIC))
-                            need += SvLEN(PL_numeric_radix_sv);
+                            float_need += SvLEN(PL_numeric_radix_sv);
                         RESTORE_LC_NUMERIC();
 #endif
                 }
                 else if (i > 0) {
-                    need = BIT_DIGITS(i);
+                    float_need = BIT_DIGITS(i);
                 } /* if i < 0, the number of digits is hard to predict. */
            }
-           need += has_precis ? precis : 6; /* known default */
 
-           if (need < width)
-               need = width;
+            {
+                STRLEN pr = has_precis ? precis : 6; /* known default */
+                if (float_need >= ((STRLEN)~0) - pr)
+                    croak_memory_wrap();
+                float_need += pr;
+            }
+
+           if (float_need < width)
+               float_need = width;
 
 #ifdef HAS_LDBL_SPRINTF_BUG
            /* This is to try to fix a bug with irix/nonstop-ux/powerux and
@@ -12341,7 +12499,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 
            if ((intsize == 'q') && (c == 'f') &&
                ((fv < MY_DBL_MAX_BUG) && (fv > -MY_DBL_MAX_BUG)) &&
-               (need < DBL_DIG)) {
+               (float_need < DBL_DIG)) {
                /* it's going to be short enough that
                 * long double precision is not needed */
 
@@ -12375,10 +12533,12 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 
 #endif /* HAS_LDBL_SPRINTF_BUG */
 
-           need += 20; /* fudge factor */
-           if (PL_efloatsize < need) {
+            if (float_need >= ((STRLEN)~0) - 40)
+                croak_memory_wrap();
+           float_need += 40; /* fudge factor */
+           if (PL_efloatsize < float_need) {
                Safefree(PL_efloatbuf);
-               PL_efloatsize = need + 20; /* more fudge */
+               PL_efloatsize = float_need;
                Newx(PL_efloatbuf, PL_efloatsize, char);
                PL_efloatbuf[0] = '\0';
            }
@@ -12747,8 +12907,11 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                         Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", ptr);
                     elen = quadmath_snprintf(PL_efloatbuf, PL_efloatsize,
                                              qfmt, nv);
-                    if ((IV)elen == -1)
+                    if ((IV)elen == -1) {
+                        if (qfmt != ptr)
+                            SAVEFREEPV(qfmt);
                         Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", qfmt);
+                    }
                     if (qfmt != ptr)
                         Safefree(qfmt);
                 }
@@ -12830,14 +12993,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                            sv_catpvn_nomg(msg, f, 1);
                        } else {
                            Perl_sv_catpvf(aTHX_ msg,
-                                          "\\%03"UVof, (UV)*f & 0xFF);
+                                          "\\%03" UVof, (UV)*f & 0xFF);
                        }
                    }
                    sv_catpvs(msg, "\"");
                } else {
                    sv_catpvs(msg, "end of string");
                }
-               Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%"SVf, SVfARG(msg)); /* yes, this is reentrant */
+               Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%" SVf, SVfARG(msg)); /* yes, this is reentrant */
            }
 
            /* output mangled stuff ... */
@@ -12876,60 +13039,89 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            }
        }
 
-        /* signed value that's wrapped? */
-        assert(elen  <= ((~(STRLEN)0) >> 1));
-       have = esignlen + zeros + elen;
-       if (have < zeros)
-           croak_memory_wrap();
-
-       need = (have > width ? have : width);
-       gap = need - have;
-
-       if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1))
-           croak_memory_wrap();
-       SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1);
-       p = SvEND(sv);
-       if (esignlen && fill == '0') {
-           int i;
-           for (i = 0; i < (int)esignlen; i++)
-               *p++ = esignbuf[i];
-       }
-       if (gap && !left) {
-           memset(p, fill, gap);
-           p += gap;
-       }
-       if (esignlen && fill != '0') {
-           int i;
-           for (i = 0; i < (int)esignlen; i++)
-               *p++ = esignbuf[i];
-       }
-       if (zeros) {
-           int i;
-           for (i = zeros; i; i--)
-               *p++ = '0';
-       }
-       if (elen) {
-           Copy(eptr, p, elen, char);
-           p += elen;
-       }
-       if (gap && left) {
-           memset(p, ' ', gap);
-           p += gap;
-       }
-       if (vectorize) {
-           if (veclen) {
-               Copy(dotstr, p, dotstrlen, char);
-               p += dotstrlen;
-           }
-           else
-               vectorize = FALSE;              /* done iterating over vecstr */
-       }
-       if (is_utf8)
-           has_utf8 = TRUE;
-       if (has_utf8)
-           SvUTF8_on(sv);
-       *p = '\0';
-       SvCUR_set(sv, p - SvPVX_const(sv));
+
+        /* append esignbuf, filler, zeros, eptr and dotstr to sv */
+
+        {
+            STRLEN need, have, gap;
+
+            /* signed value that's wrapped? */
+            assert(elen  <= ((~(STRLEN)0) >> 1));
+
+            /* Most of these length vars can range to any value if
+             * supplied with a hostile format and/or args. So check every
+             * addition for possible overflow. In reality some of these
+             * values are interdependent so these checks are slightly
+             * redundant. But its easier to be certain this way.
+             */
+
+            have = elen;
+
+            if (have >= (((STRLEN)~0) - zeros))
+                croak_memory_wrap();
+            have += zeros;
+
+            if (have >= (((STRLEN)~0) - esignlen))
+                croak_memory_wrap();
+            have += esignlen;
+
+            need = (have > width ? have : width);
+            gap = need - have;
+
+            if (need >= (((STRLEN)~0) - dotstrlen))
+                croak_memory_wrap();
+            need += dotstrlen;
+
+            if (need >= (((STRLEN)~0) - (SvCUR(sv) + 1)))
+                croak_memory_wrap();
+            need += (SvCUR(sv) + 1);
+
+            SvGROW(sv, need);
+
+            p = SvEND(sv);
+            if (esignlen && fill == '0') {
+                int i;
+                for (i = 0; i < (int)esignlen; i++)
+                    *p++ = esignbuf[i];
+            }
+            if (gap && !left) {
+                memset(p, fill, gap);
+                p += gap;
+            }
+            if (esignlen && fill != '0') {
+                int i;
+                for (i = 0; i < (int)esignlen; i++)
+                    *p++ = esignbuf[i];
+            }
+            if (zeros) {
+                int i;
+                for (i = zeros; i; i--)
+                    *p++ = '0';
+            }
+            if (elen) {
+                Copy(eptr, p, elen, char);
+                p += elen;
+            }
+            if (gap && left) {
+                memset(p, ' ', gap);
+                p += gap;
+            }
+            if (vectorize) {
+                if (veclen) {
+                    Copy(dotstr, p, dotstrlen, char);
+                    p += dotstrlen;
+                }
+                else
+                    vectorize = FALSE; /* done iterating over vecstr */
+            }
+            if (is_utf8)
+                has_utf8 = TRUE;
+            if (has_utf8)
+                SvUTF8_on(sv);
+            *p = '\0';
+            SvCUR_set(sv, p - SvPVX_const(sv));
+        }
+
        if (vectorize) {
            esignlen = 0;
            goto vector;
@@ -13024,7 +13216,7 @@ Perl_parser_dup(pTHX_ const yy_parser *const proto, CLONE_PARAMS *const param)
     parser->old_parser = NULL;
     parser->stack = NULL;
     parser->ps = NULL;
-    parser->stack_size = 0;
+    parser->stack_max1 = 0;
     /* XXX parser->stack->state = 0; */
 
     /* XXX eventually, just Copy() most of the parser struct ? */
@@ -13067,6 +13259,7 @@ Perl_parser_dup(pTHX_ const yy_parser *const proto, CLONE_PARAMS *const param)
     parser->sig_elems  = proto->sig_elems;
     parser->sig_optelems= proto->sig_optelems;
     parser->sig_slurpy  = proto->sig_slurpy;
+    parser->recheck_utf8_validity = proto->recheck_utf8_validity;
     parser->linestr    = sv_dup_inc(proto->linestr, param);
 
     {
@@ -13330,7 +13523,10 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param)
                                ? SvREFCNT_inc(av_dup_inc((const AV *)
                                                    nmg->mg_obj, param))
                                : sv_dup_inc(nmg->mg_obj, param)
-                         : sv_dup(nmg->mg_obj, param);
+                          : (nmg->mg_type == PERL_MAGIC_regdatum ||
+                             nmg->mg_type == PERL_MAGIC_regdata)
+                                  ? nmg->mg_obj
+                                  : sv_dup(nmg->mg_obj, param);
 
        if (nmg->mg_ptr && nmg->mg_type != PERL_MAGIC_regex_global) {
            if (nmg->mg_len > 0) {
@@ -13725,6 +13921,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
            switch (sv_type) {
            default:
                Perl_croak(aTHX_ "Bizarre SvTYPE [%" IVdf "]", (IV)SvTYPE(sstr));
+                NOT_REACHED; /* NOTREACHED */
                break;
 
            case SVt_PVGV:
@@ -14103,7 +14300,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
            case CXt_EVAL:
                ncx->blk_eval.old_namesv = sv_dup_inc(ncx->blk_eval.old_namesv,
                                                      param);
-                /* XXX should this sv_dup_inc? Or only if SvSCREAM ???? */
+                /* XXX should this sv_dup_inc? Or only if CxEVAL_TXT_REFCNTED ???? */
                ncx->blk_eval.cur_text  = sv_dup(ncx->blk_eval.cur_text, param);
                ncx->blk_eval.cv = cv_dup(ncx->blk_eval.cv, param);
                 /* XXX what do do with cur_top_env ???? */
@@ -14532,7 +14729,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            break;
        default:
            Perl_croak(aTHX_
-                      "panic: ss_dup inconsistency (%"IVdf")", (IV) type);
+                      "panic: ss_dup inconsistency (%" IVdf ")", (IV) type);
        }
     }
 
@@ -14921,7 +15118,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_Xpv             = (XPV*)NULL;
     my_perl->Ina       = proto_perl->Ina;
 
-    PL_statbuf         = proto_perl->Istatbuf;
     PL_statcache       = proto_perl->Istatcache;
 
 #ifndef NO_TAINT_SUPPORT
@@ -15028,9 +15224,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     /* magical thingies */
 
-    sv_setpvs(PERL_DEBUG_PAD(0), "");  /* For regex debugging. */
-    sv_setpvs(PERL_DEBUG_PAD(1), "");  /* ext/re needs these */
-    sv_setpvs(PERL_DEBUG_PAD(2), "");  /* even without DEBUGGING. */
+    SvPVCLEAR(PERL_DEBUG_PAD(0));        /* For regex debugging. */
+    SvPVCLEAR(PERL_DEBUG_PAD(1));        /* ext/re needs these */
+    SvPVCLEAR(PERL_DEBUG_PAD(2));        /* even without DEBUGGING. */
 
    
     /* Clone the regex array */
@@ -15202,6 +15398,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_GCB_invlist = sv_dup_inc(proto_perl->IGCB_invlist, param);
     PL_SB_invlist = sv_dup_inc(proto_perl->ISB_invlist, param);
     PL_WB_invlist = sv_dup_inc(proto_perl->IWB_invlist, param);
+    PL_seen_deprecated_macro = hv_dup_inc(proto_perl->Iseen_deprecated_macro, param);
     PL_utf8_mark       = sv_dup_inc(proto_perl->Iutf8_mark, param);
     PL_utf8_toupper    = sv_dup_inc(proto_perl->Iutf8_toupper, param);
     PL_utf8_totitle    = sv_dup_inc(proto_perl->Iutf8_totitle, param);
@@ -15308,7 +15505,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_watchok         = PL_watchaddr ? * PL_watchaddr : NULL;
     if (PL_debug && PL_watchaddr) {
        PerlIO_printf(Perl_debug_log,
-         "WATCHING: %"UVxf" cloned as %"UVxf" with value %"UVxf"\n",
+         "WATCHING: %" UVxf " cloned as %" UVxf " with value %" UVxf "\n",
          PTR2UV(proto_perl->Iwatchaddr), PTR2UV(PL_watchaddr),
          PTR2UV(PL_watchok));
     }
@@ -15756,7 +15953,7 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
     }
     else if (subscript_type == FUV_SUBSCRIPT_ARRAY) {
        *SvPVX(name) = '$';
-       Perl_sv_catpvf(aTHX_ name, "[%"IVdf"]", (IV)aindex);
+       Perl_sv_catpvf(aTHX_ name, "[%" IVdf "]", (IV)aindex);
     }
     else if (subscript_type == FUV_SUBSCRIPT_WITHIN) {
        /* We know that name has no magic, so can use 0 instead of SV_GMAGIC */
@@ -15806,6 +16003,11 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
 
     switch (obase->op_type) {
 
+    case OP_UNDEF:
+        /* undef should care if its args are undef - any warnings
+         * will be from tied/magic vars */
+        break;
+
     case OP_RV2AV:
     case OP_RV2HV:
     case OP_PADAV:
@@ -16352,7 +16554,6 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
     case OP_ALARM:
     case OP_SEMGET:
     case OP_GETLOGIN:
-    case OP_UNDEF:
     case OP_SUBSTR:
     case OP_AEACH:
     case OP_EACH: