This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
80-bit big-endian extraction was also wrong.
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index b6409a0..aacc3e4 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -310,7 +310,6 @@ Public API:
 STATIC SV*
 S_more_sv(pTHX)
 {
-    dVAR;
     SV* sv;
     char *chunk;                /* must use New here to match call to */
     Newx(chunk,PERL_ARENA_SIZE,char);  /* Safefree() in sv_free_arenas() */
@@ -386,8 +385,6 @@ S_new_SV(pTHX_ const char *file, int line, const char *func)
 STATIC void
 S_del_sv(pTHX_ SV *p)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_DEL_SV;
 
     if (DEBUG_D_TEST) {
@@ -432,7 +429,6 @@ and split it into a list of free SVs.
 static void
 S_sv_add_arena(pTHX_ char *const ptr, const U32 size, const U32 flags)
 {
-    dVAR;
     SV *const sva = MUTABLE_SV(ptr);
     SV* sv;
     SV* svend;
@@ -472,7 +468,6 @@ S_sv_add_arena(pTHX_ char *const ptr, const U32 size, const U32 flags)
 STATIC I32
 S_visit(pTHX_ SVFUNC_t f, const U32 flags, const U32 mask)
 {
-    dVAR;
     SV* sva;
     I32 visited = 0;
 
@@ -531,7 +526,6 @@ Perl_sv_report_used(pTHX)
 static void
 do_clean_objs(pTHX_ SV *const ref)
 {
-    dVAR;
     assert (SvROK(ref));
     {
        SV * const target = SvRV(ref);
@@ -557,7 +551,6 @@ do_clean_objs(pTHX_ SV *const ref)
 static void
 do_clean_named_objs(pTHX_ SV *const sv)
 {
-    dVAR;
     SV *obj;
     assert(SvTYPE(sv) == SVt_PVGV);
     assert(isGV_with_GP(sv));
@@ -601,7 +594,6 @@ do_clean_named_objs(pTHX_ SV *const sv)
 static void
 do_clean_named_io_objs(pTHX_ SV *const sv)
 {
-    dVAR;
     SV *obj;
     assert(SvTYPE(sv) == SVt_PVGV);
     assert(isGV_with_GP(sv));
@@ -638,7 +630,6 @@ Attempt to destroy all objects not yet freed.
 void
 Perl_sv_clean_objs(pTHX)
 {
-    dVAR;
     GV *olddef, *olderr;
     PL_in_clean_objs = TRUE;
     visit(do_clean_objs, SVf_ROK, SVf_ROK);
@@ -667,7 +658,6 @@ Perl_sv_clean_objs(pTHX)
 static void
 do_clean_all(pTHX_ SV *const sv)
 {
-    dVAR;
     if (sv == (const SV *) PL_fdpid || sv == (const SV *)PL_strtab) {
        /* don't clean pid table and strtab */
        return;
@@ -690,7 +680,6 @@ SVs which are in complex self-referential hierarchies.
 I32
 Perl_sv_clean_all(pTHX)
 {
-    dVAR;
     I32 cleaned;
     PL_in_clean_all = TRUE;
     cleaned = visit(do_clean_all, 0,0);
@@ -746,7 +735,6 @@ heads and bodies within the arenas must already have been freed.
 void
 Perl_sv_free_arenas(pTHX)
 {
-    dVAR;
     SV* sva;
     SV* svanext;
     unsigned int i;
@@ -814,6 +802,8 @@ Perl_sv_free_arenas(pTHX)
 
 =head1 SV-Body Allocation
 
+=cut
+
 Allocation of SV-bodies is similar to SV-heads, differing as follows;
 the allocation mechanism is used for many body types, so is somewhat
 more complicated, it uses arena-sets, and has no need for still-live
@@ -1074,7 +1064,6 @@ void *
 Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size,
                  const size_t arena_size)
 {
-    dVAR;
     void ** const root = &PL_body_roots[sv_type];
     struct arena_desc *adesc;
     struct arena_set *aroot = (struct arena_set *) PL_body_arenas;
@@ -1082,6 +1071,9 @@ Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size,
     char *start;
     const char *end;
     const size_t good_arena_size = Perl_malloc_good_size(arena_size);
+#if defined(DEBUGGING) && defined(PERL_GLOBAL_STRUCT)
+    dVAR;
+#endif
 #if defined(DEBUGGING) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
     static bool done_sanity_check;
 
@@ -1180,7 +1172,6 @@ Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size,
 STATIC void *
 S_new_body(pTHX_ const svtype sv_type)
 {
-    dVAR;
     void *xpv;
     new_body_inline(xpv, sv_type);
     return xpv;
@@ -1207,7 +1198,6 @@ C<svtype>.
 void
 Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
 {
-    dVAR;
     void*      old_body;
     void*      new_body;
     const svtype old_type = SvTYPE(sv);
@@ -1507,13 +1497,12 @@ wrapper instead.
 */
 
 int
-Perl_sv_backoff(pTHX_ SV *const sv)
+Perl_sv_backoff(SV *const sv)
 {
     STRLEN delta;
     const char * const s = SvPVX_const(sv);
 
     PERL_ARGS_ASSERT_SV_BACKOFF;
-    PERL_UNUSED_CONTEXT;
 
     assert(SvOOK(sv));
     assert(SvTYPE(sv) != SVt_PVHV);
@@ -1628,8 +1617,6 @@ Does not handle 'set' magic.  See also C<sv_setiv_mg>.
 void
 Perl_sv_setiv(pTHX_ SV *const sv, const IV i)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_SETIV;
 
     SV_CHECK_THINKFIRST_COW_DROP(sv);
@@ -1740,8 +1727,6 @@ Does not handle 'set' magic.  See also C<sv_setnv_mg>.
 void
 Perl_sv_setnv(pTHX_ SV *const sv, const NV num)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_SETNV;
 
     SV_CHECK_THINKFIRST_COW_DROP(sv);
@@ -1790,26 +1775,24 @@ Perl_sv_setnv_mg(pTHX_ SV *const sv, const NV num)
     SvSETMAGIC(sv);
 }
 
-/* Print an "isn't numeric" warning, using a cleaned-up,
- * printable version of the offending string
+/* Return a cleaned-up, printable version of sv, for non-numeric, or
+ * not incrementable warning display.
+ * Originally part of S_not_a_number().
+ * The return value may be != tmpbuf.
  */
 
-STATIC void
-S_not_a_number(pTHX_ SV *const sv)
-{
-     dVAR;
-     SV *dsv;
-     char tmpbuf[64];
-     const char *pv;
+STATIC const char *
+S_sv_display(pTHX_ SV *const sv, char *tmpbuf, STRLEN tmpbuf_size) {
+    const char *pv;
 
-     PERL_ARGS_ASSERT_NOT_A_NUMBER;
+     PERL_ARGS_ASSERT_SV_DISPLAY;
 
      if (DO_UTF8(sv)) {
-          dsv = newSVpvs_flags("", SVs_TEMP);
+          SV *dsv = newSVpvs_flags("", SVs_TEMP);
           pv = sv_uni_display(dsv, sv, 10, UNI_DISPLAY_ISPRINT);
      } else {
          char *d = tmpbuf;
-         const char * const limit = tmpbuf + sizeof(tmpbuf) - 8;
+         const char * const limit = tmpbuf + tmpbuf_size - 8;
          /* each *s can expand to 4 chars + "...\0",
             i.e. need room for 8 chars */
        
@@ -1860,6 +1843,23 @@ S_not_a_number(pTHX_ SV *const sv)
          pv = tmpbuf;
     }
 
+    return pv;
+}
+
+/* Print an "isn't numeric" warning, using a cleaned-up,
+ * printable version of the offending string
+ */
+
+STATIC void
+S_not_a_number(pTHX_ SV *const sv)
+{
+     char tmpbuf[64];
+     const char *pv;
+
+     PERL_ARGS_ASSERT_NOT_A_NUMBER;
+
+     pv = sv_display(sv, tmpbuf, sizeof(tmpbuf));
+
     if (PL_op)
        Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
                    /* diag_listed_as: Argument "%s" isn't numeric%s */
@@ -1871,6 +1871,19 @@ S_not_a_number(pTHX_ SV *const sv)
                    "Argument \"%s\" isn't numeric", pv);
 }
 
+STATIC void
+S_not_incrementable(pTHX_ SV *const sv) {
+     char tmpbuf[64];
+     const char *pv;
+
+     PERL_ARGS_ASSERT_NOT_INCREMENTABLE;
+
+     pv = sv_display(sv, tmpbuf, sizeof(tmpbuf));
+
+     Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
+                 "Argument \"%s\" treated as 0 in increment (++)", pv);
+}
+
 /*
 =for apidoc looks_like_number
 
@@ -2007,9 +2020,8 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
 #  endif
                       )
 {
-    dVAR;
-
     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));
     if (SvNVX(sv) < (NV)IV_MIN) {
@@ -2058,8 +2070,6 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
 STATIC bool
 S_sv_2iuv_common(pTHX_ SV *const sv)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_2IUV_COMMON;
 
     if (SvNOKp(sv)) {
@@ -2336,8 +2346,6 @@ Normally used via the C<SvIV(sv)> and C<SvIVx(sv)> macros.
 IV
 Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_2IV_FLAGS;
 
     assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV
@@ -2431,8 +2439,6 @@ Normally used via the C<SvUV(sv)> and C<SvUVx(sv)> macros.
 UV
 Perl_sv_2uv_flags(pTHX_ SV *const sv, const I32 flags)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_2UV_FLAGS;
 
     if (SvGMAGICAL(sv) && (flags & SV_GMAGIC))
@@ -2513,8 +2519,6 @@ Normally used via the C<SvNV(sv)> and C<SvNVx(sv)> macros.
 NV
 Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_2NV_FLAGS;
 
     assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV
@@ -2816,7 +2820,6 @@ C<sv_2pv()> and C<sv_2pv_nomg> usually end up here too.
 char *
 Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
 {
-    dVAR;
     char *s;
 
     PERL_ARGS_ASSERT_SV_2PV_FLAGS;
@@ -3187,8 +3190,6 @@ contain SV_GMAGIC, then it does an mg_get() first.
 bool
 Perl_sv_2bool_flags(pTHX_ SV *sv, I32 flags)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_2BOOL_FLAGS;
 
     restart:
@@ -3304,8 +3305,6 @@ especially if it could return the position of the first one.
 STRLEN
 Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV *const sv, const I32 flags, STRLEN extra)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_UTF8_UPGRADE_FLAGS_GROW;
 
     if (sv == &PL_sv_undef)
@@ -3564,8 +3563,6 @@ use the Encode extension for that.
 bool
 Perl_sv_utf8_downgrade(pTHX_ SV *const sv, const bool fail_ok)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_UTF8_DOWNGRADE;
 
     if (SvPOKp(sv) && SvUTF8(sv)) {
@@ -4103,7 +4100,6 @@ S_sv_buf_to_rw(pTHX_ SV *sv)
 void
 Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
 {
-    dVAR;
     U32 sflags;
     int dtype;
     svtype stype;
@@ -4215,7 +4211,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
        else
            Perl_croak(aTHX_ "Bizarre copy of %s", type);
        }
-       break;
+       NOT_REACHED; /* NOTREACHED */
 
     case SVt_REGEXP:
       upgregexp:
@@ -4703,7 +4699,6 @@ undefined.  Does not handle 'set' magic.  See C<sv_setpvn_mg>.
 void
 Perl_sv_setpvn(pTHX_ SV *const sv, const char *const ptr, const STRLEN len)
 {
-    dVAR;
     char *dptr;
 
     PERL_ARGS_ASSERT_SV_SETPVN;
@@ -4761,7 +4756,6 @@ Does not handle 'set' magic.  See C<sv_setpv_mg>.
 void
 Perl_sv_setpv(pTHX_ SV *const sv, const char *const ptr)
 {
-    dVAR;
     STRLEN len;
 
     PERL_ARGS_ASSERT_SV_SETPV;
@@ -4802,8 +4796,6 @@ Perl_sv_setpv_mg(pTHX_ SV *const sv, const char *const ptr)
 void
 Perl_sv_sethek(pTHX_ SV *const sv, const HEK *const hek)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_SETHEK;
 
     if (!hek) {
@@ -4873,7 +4865,6 @@ C<len>, and already meets the requirements for storing in C<SvPVX>).
 void
 Perl_sv_usepvn_flags(pTHX_ SV *const sv, char *ptr, const STRLEN len, const U32 flags)
 {
-    dVAR;
     STRLEN allocate;
 
     PERL_ARGS_ASSERT_SV_USEPVN_FLAGS;
@@ -4996,8 +4987,6 @@ of.  Hence, it croaks on read-only values.
 static void
 S_sv_uncow(pTHX_ SV * const sv, const U32 flags)
 {
-    dVAR;
-
     assert(SvIsCOW(sv));
     {
 #ifdef PERL_ANY_COW
@@ -5270,7 +5259,6 @@ in terms of this function.
 void
 Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, const I32 flags)
 {
-    dVAR;
     STRLEN dlen;
     const char * const dstr = SvPV_force_flags(dsv, dlen, flags);
 
@@ -5336,8 +5324,6 @@ and C<sv_catsv_mg> are implemented in terms of this function.
 void
 Perl_sv_catsv_flags(pTHX_ SV *const dsv, SV *const ssv, const I32 flags)
 {
-    dVAR;
     PERL_ARGS_ASSERT_SV_CATSV_FLAGS;
 
     if (ssv) {
@@ -5367,7 +5353,6 @@ valid UTF-8.  Handles 'get' magic, but not 'set' magic.  See C<sv_catpv_mg>.
 void
 Perl_sv_catpv(pTHX_ SV *const sv, const char *ptr)
 {
-    dVAR;
     STRLEN len;
     STRLEN tlen;
     char *junk;
@@ -5443,7 +5428,6 @@ modules supporting older perls.
 SV *
 Perl_newSV(pTHX_ const STRLEN len)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -5476,7 +5460,6 @@ MAGIC *
 Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, 
                 const MGVTBL *const vtable, const char *const name, const I32 namlen)
 {
-    dVAR;
     MAGIC* mg;
 
     PERL_ARGS_ASSERT_SV_MAGICEXT;
@@ -5584,7 +5567,6 @@ void
 Perl_sv_magic(pTHX_ SV *const sv, SV *const obj, const int how,
              const char *const name, const I32 namlen)
 {
-    dVAR;
     const MGVTBL *vtable;
     MAGIC* mg;
     unsigned int flags;
@@ -5791,7 +5773,6 @@ Perl_sv_rvweaken(pTHX_ SV *const sv)
 void
 Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv)
 {
-    dVAR;
     SV **svp;
     AV *av = NULL;
     MAGIC *mg = NULL;
@@ -5852,7 +5833,6 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv)
 void
 Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv)
 {
-    dVAR;
     SV **svp = NULL;
 
     PERL_ARGS_ASSERT_SV_DEL_BACKREF;
@@ -5901,7 +5881,7 @@ Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv)
        if (PL_phase == PERL_PHASE_DESTRUCT && SvREFCNT(tsv) == 0)
            return;
        Perl_croak(aTHX_ "panic: del_backref, *svp=%p phase=%s refcnt=%" UVuf,
-                  *svp, PL_phase_names[PL_phase], (UV)SvREFCNT(tsv));
+                  (void*)*svp, PL_phase_names[PL_phase], (UV)SvREFCNT(tsv));
     }
 
     if (SvTYPE(*svp) == SVt_PVAV) {
@@ -5960,7 +5940,8 @@ Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv)
     else {
        /* optimisation: only a single backref, stored directly */
        if (*svp != sv)
-           Perl_croak(aTHX_ "panic: del_backref, *svp=%p, sv=%p", *svp, sv);
+           Perl_croak(aTHX_ "panic: del_backref, *svp=%p, sv=%p",
+                       (void*)*svp, (void*)sv);
        *svp = NULL;
     }
 
@@ -6073,7 +6054,6 @@ 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)
 {
-    dVAR;
     char *big;
     char *mid;
     char *midend;
@@ -6171,7 +6151,6 @@ time you'll want to use C<sv_setsv> or one of its many macro front-ends.
 void
 Perl_sv_replace(pTHX_ SV *const sv, SV *const nsv)
 {
-    dVAR;
     const U32 refcnt = SvREFCNT(sv);
 
     PERL_ARGS_ASSERT_SV_REPLACE;
@@ -6649,8 +6628,6 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
 
 static bool
 S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
-    dVAR;
-
     PERL_ARGS_ASSERT_CURSE;
     assert(SvOBJECT(sv));
 
@@ -6910,7 +6887,6 @@ Perl_sv_len_utf8(pTHX_ SV *const sv)
 STRLEN
 Perl_sv_len_utf8_nomg(pTHX_ SV * const sv)
 {
-    dVAR;
     STRLEN len;
     const U8 *s = (U8*)SvPV_nomg_const(sv, len);
 
@@ -7585,7 +7561,6 @@ if necessary.  If the flags include SV_GMAGIC, it handles get-magic, too.
 I32
 Perl_sv_eq_flags(pTHX_ SV *sv1, SV *sv2, const U32 flags)
 {
-    dVAR;
     const char *pv1;
     STRLEN cur1;
     const char *pv2;
@@ -7687,7 +7662,6 @@ I32
 Perl_sv_cmp_flags(pTHX_ SV *const sv1, SV *const sv2,
                  const U32 flags)
 {
-    dVAR;
     STRLEN cur1, cur2;
     const char *pv1, *pv2;
     I32  cmp;
@@ -7783,7 +7757,6 @@ I32
 Perl_sv_cmp_locale_flags(pTHX_ SV *const sv1, SV *const sv2,
                         const U32 flags)
 {
-    dVAR;
 #ifdef USE_LOCALE_COLLATE
 
     char *pv1, *pv2;
@@ -7856,7 +7829,6 @@ settings.
 char *
 Perl_sv_collxfrm_flags(pTHX_ SV *const sv, STRLEN *const nxp, const I32 flags)
 {
-    dVAR;
     MAGIC *mg;
 
     PERL_ARGS_ASSERT_SV_COLLXFRM_FLAGS;
@@ -8047,7 +8019,6 @@ in the SV (typically, C<SvCUR(sv)> is a suitable choice).
 char *
 Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
 {
-    dVAR;
     const char *rsptr;
     STRLEN rslen;
     STDCHAR rslast;
@@ -8292,9 +8263,9 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
     DEBUG_P(PerlIO_printf(Perl_debug_log,
        "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=%zd, base=%"
+       "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"
         UVuf"\n",
-              PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
+              PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
               PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0)));
 
     for (;;) {
@@ -8339,13 +8310,13 @@ 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=%zd\n",
-                             PTR2UV(ptr),cnt));
+                            "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=%zd, base=%"UVuf"\n",
-           PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
+          "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)));
 
         /*
@@ -8360,16 +8331,16 @@ 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=%zd, base=%"UVuf"\n",
-           PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
+          "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)));
 
         /* find out how much is left in the read-ahead buffer, and rextract its pointer */
        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=%zd\n",
-            PTR2UV(ptr),cnt));
+           "Screamer: after getc, ptr=%"UVuf", cnt=%"IVdf"\n",
+           PTR2UV(ptr),(IV)cnt));
 
        if (i == EOF)                   /* all done for ever? */
            goto thats_really_all_folks;
@@ -8398,12 +8369,12 @@ thats_really_all_folks:
     if (shortbuffered)
        cnt += shortbuffered;
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-           "Screamer: quitting, ptr=%"UVuf", cnt=%zd\n",PTR2UV(ptr),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=%zd, base=%"UVuf
+       "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf
        "\n",
-       PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
+       PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp),
        PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
     *bp = '\0';
     SvCUR_set(sv, bp - (STDCHAR*)SvPVX_const(sv));     /* set length */
@@ -8517,7 +8488,6 @@ if necessary.  Handles operator overloading.  Skips handling 'get' magic.
 void
 Perl_sv_inc_nomg(pTHX_ SV *const sv)
 {
-    dVAR;
     char *d;
     int flags;
 
@@ -8590,11 +8560,11 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
     while (isALPHA(*d)) d++;
     while (isDIGIT(*d)) d++;
     if (d < SvEND(sv)) {
+       const int numtype = grok_number_flags(SvPVX_const(sv), SvCUR(sv), NULL, PERL_SCAN_TRAILING);
 #ifdef PERL_PRESERVE_IVUV
        /* Got to punt this as an integer if needs be, but we don't issue
           warnings. Probably ought to make the sv_iv_please() that does
           the conversion if possible, and silently.  */
-       const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), NULL);
        if (numtype && !(numtype & IS_NUMBER_INFINITY)) {
            /* Need to try really hard to see if it's an integer.
               9.22337203685478e+18 is an integer.
@@ -8625,6 +8595,8 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
 #endif
        }
 #endif /* PERL_PRESERVE_IVUV */
+        if (!numtype && ckWARN(WARN_NUMERIC))
+            not_incrementable(sv);
        sv_setnv(sv,Atof(SvPVX_const(sv)) + 1.0);
        return;
     }
@@ -8679,7 +8651,6 @@ if necessary.  Handles 'get' magic and operator overloading.
 void
 Perl_sv_dec(pTHX_ SV *const sv)
 {
-    dVAR;
     if (!sv)
        return;
     SvGETMAGIC(sv);
@@ -8698,7 +8669,6 @@ if necessary.  Handles operator overloading.  Skips handling 'get' magic.
 void
 Perl_sv_dec_nomg(pTHX_ SV *const sv)
 {
-    dVAR;
     int flags;
 
     if (!sv)
@@ -8835,7 +8805,6 @@ statement boundaries.  See also C<sv_newmortal> and C<sv_2mortal>.
 SV *
 Perl_sv_mortalcopy_flags(pTHX_ SV *const oldstr, U32 flags)
 {
-    dVAR;
     SV *sv;
 
     if (flags & SV_GMAGIC)
@@ -8861,7 +8830,6 @@ See also C<sv_mortalcopy> and C<sv_2mortal>.
 SV *
 Perl_sv_newmortal(pTHX)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -8895,7 +8863,6 @@ C<newSVpvn_utf8()> is a convenience wrapper for this function, defined as
 SV *
 Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags)
 {
-    dVAR;
     SV *sv;
 
     /* All the flags we don't support must be zero.
@@ -8963,7 +8930,6 @@ For efficiency, consider using C<newSVpvn> instead.
 SV *
 Perl_newSVpv(pTHX_ const char *const s, const STRLEN len)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -8987,9 +8953,7 @@ undefined.
 SV *
 Perl_newSVpvn(pTHX_ const char *const buffer, const STRLEN len)
 {
-    dVAR;
     SV *sv;
-
     new_SV(sv);
     sv_setpvn(sv,buffer,len);
     return sv;
@@ -9008,7 +8972,6 @@ SV if the hek is NULL.
 SV *
 Perl_newSVhek(pTHX_ const HEK *const hek)
 {
-    dVAR;
     if (!hek) {
        SV *sv;
 
@@ -9176,7 +9139,6 @@ Perl_newSVpvf(pTHX_ const char *const pat, ...)
 SV *
 Perl_vnewSVpvf(pTHX_ const char *const pat, va_list *const args)
 {
-    dVAR;
     SV *sv;
 
     PERL_ARGS_ASSERT_VNEWSVPVF;
@@ -9198,7 +9160,6 @@ The reference count for the SV is set to 1.
 SV *
 Perl_newSVnv(pTHX_ const NV n)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -9218,7 +9179,6 @@ SV is set to 1.
 SV *
 Perl_newSViv(pTHX_ const IV i)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -9238,7 +9198,6 @@ The reference count for the SV is set to 1.
 SV *
 Perl_newSVuv(pTHX_ const UV u)
 {
-    dVAR;
     SV *sv;
 
     new_SV(sv);
@@ -9277,7 +9236,6 @@ SV is B<not> incremented.
 SV *
 Perl_newRV_noinc(pTHX_ SV *const tmpRef)
 {
-    dVAR;
     SV *sv = newSV_type(SVt_IV);
 
     PERL_ARGS_ASSERT_NEWRV_NOINC;
@@ -9295,8 +9253,6 @@ Perl_newRV_noinc(pTHX_ SV *const tmpRef)
 SV *
 Perl_newRV(pTHX_ SV *const sv)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_NEWRV;
 
     return newRV_noinc(SvREFCNT_inc_simple_NN(sv));
@@ -9314,7 +9270,6 @@ Creates a new SV which is an exact duplicate of the original SV.
 SV *
 Perl_newSVsv(pTHX_ SV *const old)
 {
-    dVAR;
     SV *sv;
 
     if (!old)
@@ -9352,7 +9307,6 @@ Perl_sv_reset(pTHX_ const char *s, HV *const stash)
 void
 Perl_sv_resetpvn(pTHX_ const char *s, STRLEN len, HV * const stash)
 {
-    dVAR;
     char todo[PERL_UCHAR_MAX+1];
     const char *send;
 
@@ -9497,7 +9451,6 @@ The flags in C<lref> are passed to gv_fetchsv.
 CV *
 Perl_sv_2cv(pTHX_ SV *sv, HV **const st, GV **const gvp, const I32 lref)
 {
-    dVAR;
     GV *gv = NULL;
     CV *cv = NULL;
 
@@ -9621,8 +9574,6 @@ C<SvPV_force> and C<SvPV_force_nomg>
 char *
 Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS;
 
     if (flags & SV_GMAGIC) SvGETMAGIC(sv);
@@ -9866,7 +9817,6 @@ reference count is 1.  The reference count 1 is owned by C<rv>.
 SV*
 Perl_newSVrv(pTHX_ SV *const rv, const char *const classname)
 {
-    dVAR;
     SV *sv;
 
     PERL_ARGS_ASSERT_NEWSVRV;
@@ -9934,8 +9884,6 @@ Note that C<sv_setref_pvn> copies the string while this copies the pointer.
 SV*
 Perl_sv_setref_pv(pTHX_ SV *const rv, const char *const classname, void *const pv)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_SETREF_PV;
 
     if (!pv) {
@@ -10048,7 +9996,6 @@ of the SV is unaffected.
 SV*
 Perl_sv_bless(pTHX_ SV *const sv, HV *const stash)
 {
-    dVAR;
     SV *tmpRef;
     HV *oldstash = NULL;
 
@@ -10086,7 +10033,6 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash)
 PERL_STATIC_INLINE void
 S_sv_unglob(pTHX_ SV *const sv, U32 flags)
 {
-    dVAR;
     void *xpvmg;
     HV *stash;
     SV * const temp = flags & SV_COW_DROP_PV ? NULL : sv_newmortal();
@@ -10186,6 +10132,7 @@ void
 Perl_sv_untaint(pTHX_ SV *const sv)
 {
     PERL_ARGS_ASSERT_SV_UNTAINT;
+    PERL_UNUSED_CONTEXT;
 
     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
        MAGIC * const mg = mg_find(sv, PERL_MAGIC_taint);
@@ -10206,6 +10153,7 @@ bool
 Perl_sv_tainted(pTHX_ SV *const sv)
 {
     PERL_ARGS_ASSERT_SV_TAINTED;
+    PERL_UNUSED_CONTEXT;
 
     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
        const MAGIC * const mg = mg_find(sv, PERL_MAGIC_taint);
@@ -10521,7 +10469,6 @@ Perl_sv_vsetpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
  * Warn of missing argument to sprintf, and then return a defined value
  * to avoid inappropriate "use of uninit" warnings [perl #71000].
  */
-#define WARN_MISSING WARN_UNINITIALIZED /* Not sure we want a new category */
 STATIC SV*
 S_vcatpvfn_missing_argument(pTHX) {
     if (ckWARN(WARN_MISSING)) {
@@ -10535,7 +10482,6 @@ S_vcatpvfn_missing_argument(pTHX) {
 STATIC I32
 S_expect_number(pTHX_ char **const pattern)
 {
-    dVAR;
     I32 var = 0;
 
     PERL_ARGS_ASSERT_EXPECT_NUMBER;
@@ -10622,7 +10568,6 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                        va_list *const args, SV **const svargs, const I32 svmax, bool *const maybe_tainted,
                        const U32 flags)
 {
-    dVAR;
     char *p;
     char *q;
     const char *patend;
@@ -10639,6 +10584,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
     char ebuf[IV_DIG * 4 + NV_DIG + 32];
     /* large enough for "%#.#f" --chip */
     /* what about long double NVs? --jhi */
+    bool no_redundant_warning = FALSE; /* did we use any explicit format parameter index? */
+    bool hexfp = FALSE;
 
     DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED;
 
@@ -10652,9 +10599,17 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
     (void)SvPV_force_nomg(sv, origlen);
 
     /* special-case "", "%s", and "%-p" (SVf - see below) */
-    if (patlen == 0)
+    if (patlen == 0) {
+       if (svmax && ckWARN(WARN_REDUNDANT))
+           Perl_warner(aTHX_ packWARN(WARN_REDUNDANT), "Redundant argument in %s",
+                       PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()");
        return;
+    }
     if (patlen == 2 && pat[0] == '%' && pat[1] == 's') {
+       if (svmax > 1 && ckWARN(WARN_REDUNDANT))
+           Perl_warner(aTHX_ packWARN(WARN_REDUNDANT), "Redundant argument in %s",
+                       PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()");
+
        if (args) {
            const char * const s = va_arg(*args, char*);
            sv_catpv_nomg(sv, s ? s : nullstr);
@@ -10670,6 +10625,9 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
     }
     if (args && patlen == 3 && pat[0] == '%' &&
                pat[1] == '-' && pat[2] == 'p') {
+       if (svmax > 1 && ckWARN(WARN_REDUNDANT))
+           Perl_warner(aTHX_ packWARN(WARN_REDUNDANT), "Redundant argument in %s",
+                       PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()");
        argsv = MUTABLE_SV(va_arg(*args, void*));
        sv_catsv_nomg(sv, argsv);
        return;
@@ -10685,6 +10643,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
        pp = pat + 2;
        while (*pp >= '0' && *pp <= '9')
            digits = 10 * digits + (*pp++ - '0');
+
+       /* XXX: Why do this `svix < svmax` test? Couldn't we just
+          format the first argument and WARN_REDUNDANT if svmax > 1?
+          Munged by Nicholas Clark in v5.13.0-209-g95ea86d */
        if (pp - pat == (int)patlen - 1 && svix < svmax) {
            const NV nv = SvNV(*svargs);
            if (*pp == 'g') {
@@ -10865,6 +10827,11 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            if (*q == '$') {
                ++q;
                efix = width;
+               if (!no_redundant_warning)
+                   /* I've forgotten if it's a better
+                      micro-optimization to always set this or to
+                      only set it if it's unset */
+                   no_redundant_warning = TRUE;
            } else {
                goto gotwidth;
            }
@@ -11346,10 +11313,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            {
                char *ptr = ebuf + sizeof ebuf;
                bool tempalt = uv ? alt : FALSE; /* Vectors can't change alt */
+                unsigned dig;
                zeros = 0;
 
                switch (base) {
-                   unsigned dig;
                case 16:
                    p = (char *)((c == 'X') ? PL_hexdigit + 16 : PL_hexdigit);
                    do {
@@ -11410,6 +11377,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
        case 'e': case 'E':
        case 'f':
        case 'g': case 'G':
+       case 'a': case 'A':
            if (vectorize)
                goto unknown;
 
@@ -11462,14 +11430,42 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            /* nv * 0 will be NaN for NaN, +Inf and -Inf, and 0 for anything
               else. frexp() has some unspecified behaviour for those three */
            if (c != 'e' && c != 'E' && (nv * 0) == 0) {
-               i = PERL_INT_MIN;
-               /* FIXME: if HAS_LONG_DOUBLE but not USE_LONG_DOUBLE this
-                  will cast our (long double) to (double) */
-               (void)Perl_frexp(nv, &i);
-               if (i == PERL_INT_MIN)
-                   Perl_die(aTHX_ "panic: frexp");
-               if (i > 0)
-                   need = BIT_DIGITS(i);
+                i = PERL_INT_MIN;
+                /* FIXME: if HAS_LONG_DOUBLE but not USE_LONG_DOUBLE this
+                   will cast our (long double) to (double) */
+                (void)Perl_frexp(nv, &i);
+                if (i == PERL_INT_MIN)
+                    Perl_die(aTHX_ "panic: frexp");
+                hexfp = (c == 'a' || c == 'A');
+                if (UNLIKELY(hexfp)) {
+                    /* Hexadecimal floating point: this size
+                     * computation probably overshoots, but that is
+                     * better than undershooting. */
+                    need +=
+                        (nv < 0) + /* possible unary minus */
+                        2 + /* "0x" */
+                        1 + /* the very unlikely carry */
+                        1 + /* "1" */
+                        1 + /* "." */
+                        /* We want one byte per each 4 bits in the
+                         * mantissa.  This works out to about 0.83
+                         * bytes per NV decimal digit (of 4 bits):
+                         * (NV_DIG * log(10)/log(2)) / 4,
+                         * we overestimate by using 5/6 (0.8333...) */
+                        ((NV_DIG * 5) / 6 + 1) +
+                        2 + /* "p+" */
+                        (i >= 0 ? BIT_DIGITS(i) : 1 + BIT_DIGITS(-i)) +
+                        1;   /* \0 */
+#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);
+                        RESTORE_LC_NUMERIC();
+#endif
+                }
+                else if (i > 0) {
+                    need = BIT_DIGITS(i);
+                } /* if i < 0, the number of digits is hard to predict. */
            }
            need += has_precis ? precis : 6; /* known default */
 
@@ -11567,7 +11563,324 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                        break;
                }
            }
-           {
+
+            if (UNLIKELY(hexfp)) {
+                /* Hexadecimal floating point. */
+                char* p = PL_efloatbuf;
+                /* vdig will contain the values (0..15) of the hex
+                 * digits ("nybbles" of 4 bits); at most 128 bits
+                 * mantissa, 4 bits per xdigit. */
+                U8 vdig[128 / 4];
+                U8* v = vdig; /* working pointer to vdig */
+                U8* vend; /* pointer to one beyond last of vdig */
+                U8* vfnz = NULL; /* first non-zero */
+                const bool lower = (c == 'a');
+                /* At output the values of vdig (up to vend) will
+                 * be mapped through the xdig to get the actual
+                 * human-readable xdigits. */
+                const char* xdig = PL_hexdigit;
+                int zerotail = 0; /* how many extra zeros to append */
+                int exponent; /* exponent of the floating point input */
+                int ix; /* working horse index */
+
+                /* If we do not have a known long double format,
+                 * (including not using long doubles, or long doubles
+                 * being equal to doubles) then we will fall back to
+                 * the ldexp/frexp route, with which we can retrieve
+                 * at most as many bits as our widest unsigned integer
+                 * type is.  We try to get a 64-bit unsigned integer
+                 * even if we are not having 64-bit UV. */
+#if defined(HAS_QUAD) && defined(Uquad_t)
+#  define MANTISSATYPE Uquad_t
+#  define MANTISSASIZE 8
+#else
+#  define MANTISSATYPE UV /* May lose precision if UVSIZE is not 8. */
+#  define MANTISSASIZE UVSIZE
+#endif
+
+                /* First we see if we are using long doubles. */
+
+#if NVSIZE > DOUBLESIZE && LONG_DOUBLEKIND != LONG_DOUBLE_IS_DOUBLE
+                {
+                    const U8* nvp = (const U8*)(&nv);
+                    (void)Perl_frexp(PERL_ABS(nv), &exponent);
+#  if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+                    /* The bytes 15..0 are the mantissa/fraction */
+                    for (ix = 15; ix >= 0; ix--) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+                    /* Used in e.g. Solaris Sparc and HP-PA HP-UX, e.g.
+                     * bf fb 99 99 99 99 99 99 99 99 99 99 99 99 99 9a */
+                    /* The bytes 0..15 are the mantissa/fraction */
+                    for (ix = 0; ix <= 15; ix++) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
+                    /* x86 80-bit "extended precision", 64 bits of
+                     * mantissa/fraction/significand, 15 bits of exponent,
+                     * 1 bit of sign.  NVSIZE can be either 12 (ILP32,
+                     * Solaris x86) or 16 (LP64, Linux and OS X),
+                     * meaning that 4 or 6 bytes are empty padding. */
+                    /* The bytes 7..0 are the mantissa/fraction */
+                    for (ix = 7; ix >= 0; ix--) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+                    /* The last 8 bytes are the mantissa/fraction.
+                     * (does this format ever happen?) */
+                    for (ix = LONGDBLSIZE - 8; ix < LONGDBLSIZE; ix++) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+                    /* XXX: implement, the mantissa/fraction bits are in
+                     * two separate stretches. */
+#   define LONGDOUBLE_FALLBACK
+                    goto frexp_ldexp_fallback;
+#  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+                    /* XXX: implement, the mantissa/fraction bits are in
+                     * two separate stretches. */
+                    /* Used in e.g. PPC/Power and MIPS. */
+                    /* -0.1L:
+                     * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a
+                     * as seen in PowerPC AIX, as opposed to "true" 128-bit
+                     * IEEE 754:
+                     * bf fb 99 99 99 99 99 99 99 99 99 99 99 99 99 9a
+                     * as seen in HP-PA HP-UX. */
+#   define LONGDOUBLE_FALLBACK
+                    goto frexp_ldexp_fallback;
+#  else
+                    Perl_croak(aTHX_
+                               "Hexadecimal float: unsupported long double format");
+#  endif
+                }
+
+#  ifdef LONGDOUBLE_FALLBACK
+            frexp_ldexp_fallback:
+#  endif
+#else
+                {
+                    /* If not using long doubles (or if the long double
+                     * format is known but not yet supported), try to
+                     * retrieve the mantissa bits via frexp+ldexp. */
+
+                    NV norm = Perl_frexp(PERL_ABS(nv), &exponent);
+                    /* Theoretically we have all the bytes [0, MANTISSASIZE-1]
+                     * to inspect; but in practice we don't want the
+                     * leading nybbles that are zero.  With the common
+                     * IEEE 754 value for NV_MANT_DIG being 53, we want
+                     * the limit byte to be (int)((53-1)/8) == 6.
+                     *
+                     * Note that this is _not_ inspecting the in-memory
+                     * format of the nv (as opposed to the long double
+                     * method), but instead the UV retrieved with the
+                     * frexp+ldexp invocation. */
+#  if MANTISSASIZE * 8 > NV_MANT_DIG
+                    MANTISSATYPE mantissa = Perl_ldexp(norm, NV_MANT_DIG);
+                    int limit_byte = (NV_MANT_DIG - 1) / 8;
+#  else
+                    /* There will be low-order precision loss.
+                     * Try to salvage as many bits as possible.
+                     * Will truncate, not round. */
+                    MANTISSATYPE mantissa =
+                        Perl_ldexp(norm,
+                                   /* The highest possible shift by
+                                    * two that fits in the mantissa
+                                    * and is aligned (by four) the
+                                    * same was as NV_MANT_DIG. */
+                                   MANTISSASIZE * 8 - (4 - NV_MANT_DIG % 4));
+                    int limit_byte = MANTISSASIZE - 1;
+#  endif
+                    const U8* nvp = (const U8*)(&mantissa);
+                    /* We make here the wild assumption that
+                     * the endianness of doubles is similar to
+                     * the endianness of integers, and that
+                     * there is no middle-endianness.  This may
+                     * come back to haunt us (the rumor has it
+                     * that ARM can be quite haunted).
+                     *
+                     * We generate 4-bit xdigits (nybble/nibble)
+                     * instead of 8-bit bytes, since we might need
+                     * to handle printf precision, and also insert
+                     * the radix.
+                     */
+#  if BYTEORDER == 0x12345678 || BYTEORDER == 0x1234 || \
+     LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN || \
+     LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+     LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+                    /* Little endian. */
+                    for (ix = limit_byte; ix >= 0; ix--) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  else
+                    /* Big endian. */
+                    for (ix = MANTISSASIZE - 1 - limit_byte;
+                         ix < MANTISSASIZE; ix++) {
+                        *v++ = nvp[ix] >> 4;
+                        *v++ = nvp[ix] & 0xF;
+                    }
+#  endif
+                    /* If there are not enough bits in MANTISSATYPE,
+                     * we couldn't get all of them.
+                     *
+                     * Note that NV_PRESERVES_UV_BITS would not help
+                     * here, it is the wrong way around. */
+#  if NV_MANT_DIG > MANTISSASIZE * 8
+                    Perl_ck_warner(aTHX_ packWARN(WARN_OVERFLOW),
+                                   "Hexadecimal float: precision loss");
+#  endif
+                }
+#endif
+                vend = v;
+                assert(vend > vdig);
+                assert(vend < vdig + sizeof(vdig));
+
+                if (nv < 0)
+                    *p++ = '-';
+                else if (plus)
+                    *p++ = plus;
+                *p++ = '0';
+                if (lower) {
+                    *p++ = 'x';
+                }
+                else {
+                    *p++ = 'X';
+                    xdig += 16; /* Use uppercase hex. */
+                }
+
+                /* Find the first non-zero xdigit. */
+                for (v = vdig; v < vend; v++) {
+                    if (*v) {
+                        vfnz = v;
+                        break;
+                    }
+                }
+
+                if (vfnz) {
+                    U8* vlnz = NULL; /* The last non-zero. */
+
+                    /* Find the last non-zero xdigit. */
+                    for (v = vend - 1; v >= vdig; v--) {
+                        if (*v) {
+                            vlnz = v;
+                            break;
+                        }
+                    }
+
+                    /* Adjust the exponent so that the first output
+                     * xdigit aligns with the 4-bit nybbles. */
+                    exponent -= NV_MANT_DIG % 4 ? NV_MANT_DIG % 4 : 4;
+
+                    if (precis > 0) {
+                        v = vdig + precis + 1;
+                        if (v < vend) {
+                            /* Round away from zero: if the tail
+                             * beyond the precis xdigits is equal to
+                             * or greater than 0x8000... */
+                            bool round = *v > 0x8;
+                            if (!round && *v == 0x8) {
+                                for (v++; v < vend; v++) {
+                                    if (*v) {
+                                        round = TRUE;
+                                        break;
+                                    }
+                                }
+                            }
+                            if (round) {
+                                for (v = vdig + precis; v >= vdig; v--) {
+                                    if (*v < 0xF) {
+                                        (*v)++;
+                                        break;
+                                    }
+                                    *v = 0;
+                                    if (v == vdig) {
+                                        /* If the carry goes all the way to
+                                         * the front, we need to output
+                                         * a single '1'. This goes against
+                                         * the "xdigit and then radix"
+                                         * but since this is "cannot happen"
+                                         * category, that is probably good. */
+                                        *p++ = xdig[1];
+                                    }
+                                }
+                            }
+                            /* The new effective "last non zero". */
+                            vlnz = vdig + precis;
+                        }
+                        else {
+                            zerotail = precis - (vlnz - vdig);
+                        }
+                    }
+
+                    v = vdig;
+                    *p++ = xdig[*v++];
+
+                    /* The radix is always output after the first
+                     * non-zero xdigit, or if alt.  */
+                    if (vfnz < vlnz || alt) {
+#ifndef USE_LOCALE_NUMERIC
+                        *p++ = '.';
+#else
+                        STORE_LC_NUMERIC_SET_TO_NEEDED();
+                        if (PL_numeric_radix_sv && IN_LC(LC_NUMERIC)) {
+                            STRLEN n;
+                            const char* r = SvPV(PL_numeric_radix_sv, n);
+                            Copy(r, p, n, char);
+                            p += n;
+                        }
+                        else {
+                            *p++ = '.';
+                        }
+                        RESTORE_LC_NUMERIC();
+#endif
+                    }
+
+                    while (v <= vlnz)
+                        *p++ = xdig[*v++];
+
+                    while (zerotail--)
+                        *p++ = '0';
+                }
+                else {
+                    *p++ = '0';
+                    exponent = 0;
+                }
+
+                elen = p - PL_efloatbuf;
+                elen += my_snprintf(p, PL_efloatsize - elen,
+                                    "%c%+d", lower ? 'p' : 'P',
+                                    exponent);
+
+                if (elen < width) {
+                    if (left) {
+                        /* Pad the back with spaces. */
+                        memset(PL_efloatbuf + elen, ' ', width - elen);
+                    }
+                    else if (fill == '0') {
+                        /* Insert the zeros between the "0x" and
+                         * the digits, otherwise we end up with
+                         * "0000xHHH..." */
+                        STRLEN nzero = width - elen;
+                        char* zerox = PL_efloatbuf + 2;
+                        Move(zerox, zerox + nzero,  elen - 2, char);
+                        memset(zerox, fill, nzero);
+                    }
+                    else {
+                        /* Move it to the right. */
+                        Move(PL_efloatbuf, PL_efloatbuf + width - elen,
+                             elen, char);
+                        /* Pad the front with spaces. */
+                        memset(PL_efloatbuf, ' ', width - elen);
+                    }
+                    elen = width;
+                }
+            }
+            else {
                char *ptr = ebuf + sizeof ebuf;
                *--ptr = '\0';
                *--ptr = c;
@@ -11611,14 +11924,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                  * that is safe to use, even though it's not literal */
                 GCC_DIAG_IGNORE(-Wformat-nonliteral);
 #if defined(HAS_LONG_DOUBLE)
-               elen = ((intsize == 'q')
-                       ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
-                       : my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv));
+                elen = ((intsize == 'q')
+                        ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
+                        : my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv));
 #else
-               elen = my_sprintf(PL_efloatbuf, ptr, nv);
+                elen = my_sprintf(PL_efloatbuf, ptr, nv);
 #endif
                 GCC_DIAG_RESTORE;
            }
+
        float_converted:
            eptr = PL_efloatbuf;
 
@@ -11789,6 +12103,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            goto vector;
        }
     }
+
+    /* Now that we've consumed all our printf format arguments (svix)
+     * do we have things left on the stack that we didn't use?
+     */
+    if (!no_redundant_warning && svmax >= svix + 1 && ckWARN(WARN_REDUNDANT)) {
+       Perl_warner(aTHX_ packWARN(WARN_REDUNDANT), "Redundant argument in %s",
+               PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()");
+    }
+
     SvTAINT(sv);
 
     RESTORE_LC_NUMERIC();   /* Done outside loop, so don't have to save/restore
@@ -11928,27 +12251,9 @@ Perl_parser_dup(pTHX_ const yy_parser *const proto, CLONE_PARAMS *const param)
     Copy(proto->tokenbuf, parser->tokenbuf, 256, char);
 
 
-#ifdef PERL_MAD
-    parser->endwhite   = proto->endwhite;
-    parser->faketokens = proto->faketokens;
-    parser->lasttoke   = proto->lasttoke;
-    parser->nextwhite  = proto->nextwhite;
-    parser->realtokenstart = proto->realtokenstart;
-    parser->skipwhite  = proto->skipwhite;
-    parser->thisclose  = proto->thisclose;
-    parser->thismad    = proto->thismad;
-    parser->thisopen   = proto->thisopen;
-    parser->thisstuff  = proto->thisstuff;
-    parser->thistoken  = proto->thistoken;
-    parser->thiswhite  = proto->thiswhite;
-
-    Copy(proto->nexttoke, parser->nexttoke, 5, NEXTTOKE);
-    parser->curforce   = proto->curforce;
-#else
     Copy(proto->nextval, parser->nextval, 5, YYSTYPE);
     Copy(proto->nexttype, parser->nexttype, 5, I32);
     parser->nexttoke   = proto->nexttoke;
-#endif
 
     /* XXX should clone saved_curcop here, but we aren't passed
      * proto_perl; so do it in perl_clone_using instead */
@@ -12061,8 +12366,8 @@ Perl_dirp_dup(pTHX_ DIR *const dp, CLONE_PARAMS *const param)
        for(;;) {
            pos = PerlDir_tell(ret);
            if ((dirent = PerlDir_read(ret))) {
-               if (len == d_namlen(dirent)
-                && memEQ(name, dirent->d_name, len)) {
+               if (len == (STRLEN)d_namlen(dirent)
+                    && memEQ(name, dirent->d_name, len)) {
                    /* found it */
                    PerlDir_seek(ret, pos); /* step back */
                    break;
@@ -14295,8 +14600,6 @@ The PV of the sv is returned.
 char *
 Perl_sv_recode_to_utf8(pTHX_ SV *sv, SV *encoding)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_SV_RECODE_TO_UTF8;
 
     if (SvPOK(sv) && !SvUTF8(sv) && !IN_BYTES && SvROK(encoding)) {
@@ -14374,7 +14677,6 @@ bool
 Perl_sv_cat_decode(pTHX_ SV *dsv, SV *encoding,
                   SV *ssv, int *offset, char *tstr, int tlen)
 {
-    dVAR;
     bool ret = FALSE;
 
     PERL_ARGS_ASSERT_SV_CAT_DECODE;
@@ -14460,8 +14762,6 @@ S_find_hash_subscript(pTHX_ const HV *const hv, const SV *const val)
 STATIC I32
 S_find_array_subscript(pTHX_ const AV *const av, const SV *const val)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_FIND_ARRAY_SUBSCRIPT;
 
     if (!av || SvMAGICAL(av) || !AvARRAY(av) ||
@@ -14695,7 +14995,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
            return varname(gv, '$', 0,
                    NULL, (I8)obase->op_private, FUV_SUBSCRIPT_ARRAY);
        }
-       break;
+       NOT_REACHED; /* NOTREACHED */
 
     case OP_EXISTS:
        o = cUNOPx(obase)->op_first;
@@ -14797,7 +15097,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
                ? '@' : '%',
                o->op_targ, NULL, 0, FUV_SUBSCRIPT_WITHIN);
        }
-       break;
+       NOT_REACHED; /* NOTREACHED */
     }
 
     case OP_AASSIGN:
@@ -14809,9 +15109,9 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
        if (   o->op_type == OP_PUSHMARK
           || (o->op_type == OP_NULL && o->op_targ == OP_PUSHMARK)
         )
-           o = o->op_sibling;
+           o = OP_SIBLING(o);
 
-       if (!o->op_sibling) {
+       if (!OP_HAS_SIBLING(o)) {
            /* one-arg version of open is highly magical */
 
            if (o->op_type == OP_GV) { /* open FOO; */
@@ -14856,7 +15156,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
             &&
                (   o->op_type == OP_PUSHMARK
                || (o->op_type == OP_NULL && o->op_targ == OP_PUSHMARK)))
-           o = o->op_sibling->op_sibling;
+           o = OP_SIBLING(OP_SIBLING(o));
        goto do_op2;
 
 
@@ -14987,7 +15287,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
          * it replaced are still in the tree, so we work on them instead.
         */
        o2 = NULL;
-       for (kid=o; kid; kid = kid->op_sibling) {
+       for (kid=o; kid; kid = OP_SIBLING(kid)) {
            const OPCODE type = kid->op_type;
            if ( (type == OP_CONST && SvOK(cSVOPx_sv(kid)))
              || (type == OP_NULL  && ! (kid->op_flags & OPf_KIDS))
@@ -15010,7 +15310,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
            sv = find_uninit_var(o, uninit_sv, 1);
            if (sv)
                return sv;
-           o = o->op_sibling;
+           o = OP_SIBLING(o);
        }
        break;
     }
@@ -15029,7 +15329,6 @@ Print appropriate "Use of uninitialized variable" warning.
 void
 Perl_report_uninit(pTHX_ const SV *uninit_sv)
 {
-    dVAR;
     if (PL_op) {
        SV* varname = NULL;
        if (uninit_sv && PL_curpad) {