This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix special-case recreation of *::
[perl5.git] / gv.c
diff --git a/gv.c b/gv.c
index cdfdc8d..ae800c9 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -34,7 +34,7 @@ Perl stores its global variables.
 #include "EXTERN.h"
 #define PERL_IN_GV_C
 #include "perl.h"
-#include "overload.c"
+#include "overload.inc"
 #include "keywords.h"
 #include "feature.h"
 
@@ -84,7 +84,7 @@ Perl_gv_add_by_type(pTHX_ GV *gv, svtype type)
     {
        *where = newSV_type(type);
            if (type == SVt_PVAV && GvNAMELEN(gv) == 3
-            && strnEQ(GvNAME(gv), "ISA", 3))
+            && strEQs(GvNAME(gv), "ISA"))
            sv_magic(*where, (SV *)gv, PERL_MAGIC_isa, NULL, 0);
     }
     return gv;
@@ -129,7 +129,7 @@ Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen,
        sv_setpvn(GvSV(gv), name, namelen);
 #endif
     }
-    if ((PERLDB_LINE || PERLDB_SAVESRC) && !GvAV(gv))
+    if (PERLDB_LINE_OR_SAVESRC && !GvAV(gv))
            hv_magic(GvHVn(gv), GvAVn(gv), PERL_MAGIC_dbfile);
     if (tmpbuf != smallbuf)
        Safefree(tmpbuf);
@@ -142,7 +142,7 @@ Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen,
 If C<gv> is a typeglob whose subroutine entry is a constant sub eligible for
 inlining, or C<gv> is a placeholder reference that would be promoted to such
 a typeglob, then returns the value returned by the sub.  Otherwise, returns
-NULL.
+C<NULL>.
 
 =cut
 */
@@ -155,7 +155,7 @@ Perl_gv_const_sv(pTHX_ GV *gv)
 
     if (SvTYPE(gv) == SVt_PVGV)
        return cv_const_sv(GvCVu(gv));
-    return SvROK(gv) && SvTYPE(SvRV(gv)) != SVt_PVAV ? SvRV(gv) : NULL;
+    return SvROK(gv) && SvTYPE(SvRV(gv)) != SVt_PVAV && SvTYPE(SvRV(gv)) != SVt_PVCV ? SvRV(gv) : NULL;
 }
 
 GP *
@@ -304,8 +304,8 @@ Perl_cvstash_set(pTHX_ CV *cv, HV *st)
 
 Converts a scalar into a typeglob.  This is an incoercible typeglob;
 assigning a reference to it will assign to one of its slots, instead of
-overwriting it as happens with typeglobs created by SvSetSV.  Converting
-any scalar that is SvOK() may produce unpredictable results and is reserved
+overwriting it as happens with typeglobs created by C<SvSetSV>.  Converting
+any scalar that is C<SvOK()> may produce unpredictable results and is reserved
 for perl's internal use.
 
 C<gv> is the scalar to be converted.
@@ -318,25 +318,25 @@ stash element, it is the caller's responsibility to ensure that the name
 passed to this function matches the name of the element.  If it does not
 match, perl's internal bookkeeping will get out of sync.
 
-C<flags> can be set to SVf_UTF8 if C<name> is a UTF8 string, or
+C<flags> can be set to C<SVf_UTF8> if C<name> is a UTF-8 string, or
 the return value of SvUTF8(sv).  It can also take the
-GV_ADDMULTI flag, which means to pretend that the GV has been
+C<GV_ADDMULTI> flag, which means to pretend that the GV has been
 seen before (i.e., suppress "Used once" warnings).
 
 =for apidoc gv_init
 
-The old form of gv_init_pvn().  It does not work with UTF8 strings, as it
+The old form of C<gv_init_pvn()>.  It does not work with UTF-8 strings, as it
 has no flags parameter.  If the C<multi> parameter is set, the
-GV_ADDMULTI flag will be passed to gv_init_pvn().
+C<GV_ADDMULTI> flag will be passed to C<gv_init_pvn()>.
 
 =for apidoc gv_init_pv
 
-Same as gv_init_pvn(), but takes a nul-terminated string for the name
+Same as C<gv_init_pvn()>, but takes a nul-terminated string for the name
 instead of separate char * and length parameters.
 
 =for apidoc gv_init_sv
 
-Same as gv_init_pvn(), but takes an SV * for the name instead of separate
+Same as C<gv_init_pvn()>, but takes an SV * for the name instead of separate
 char * and length parameters.  C<flags> is currently unused.
 
 =cut
@@ -385,6 +385,7 @@ Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flag
        case SVt_PVIO:
             Perl_croak(aTHX_ "Cannot convert a reference to %s to typeglob",
                       sv_reftype(has_constant, 0));
+            break;
 
        default: NOOP;
        }
@@ -530,18 +531,12 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
        return NULL;
     case KEY_chdir:
     case KEY_chomp: case KEY_chop: case KEY_defined: case KEY_delete:
-    case KEY_each : case KEY_eof : case KEY_exec   : case KEY_exists:
-    case KEY_keys:
+    case KEY_eof  : case KEY_exec: case KEY_exists :
     case KEY_lstat:
-    case KEY_pop:
-    case KEY_push:
-    case KEY_shift:
-    case KEY_splice: case KEY_split:
+    case KEY_split:
     case KEY_stat:
     case KEY_system:
     case KEY_truncate: case KEY_unlink:
-    case KEY_unshift:
-    case KEY_values:
        ampable = FALSE;
     }
     if (!gv) {
@@ -572,7 +567,9 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
     }
     CvGV_set(cv, gv); /* This stops new ATTRSUB from setting CvFILE
                          from PL_curcop. */
-    (void)gv_fetchfile(file);
+    /* XSUBs can't be perl lang/perl5db.pl debugged
+    if (PERLDB_LINE_OR_SAVESRC)
+        (void)gv_fetchfile(file); */
     CvFILE(cv) = (char *)file;
     /* XXX This is inefficient, as doing things this order causes
            a prototype check in newATTRSUB.  But we have to do
@@ -601,7 +598,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
                )) != NULL) {
             assert(GvCV(gv) == orig_cv);
             if (opnum != OP_VEC && opnum != OP_SUBSTR && opnum != OP_POS
-                && opnum != OP_UNDEF)
+                && opnum != OP_UNDEF && opnum != OP_KEYS)
                 CvLVALUE_off(cv); /* Now *that* was a neat trick. */
         }
        LEAVE;
@@ -667,16 +664,16 @@ Perl_gv_fetchmeth_pv(pTHX_ HV *stash, const char *name, I32 level, U32 flags)
 
 Returns the glob with the given C<name> and a defined subroutine or
 C<NULL>.  The glob lives in the given C<stash>, or in the stashes
-accessible via @ISA and UNIVERSAL::.
+accessible via C<@ISA> and C<UNIVERSAL::>.
 
 The argument C<level> should be either 0 or -1.  If C<level==0>, as a
 side-effect creates a glob with the given C<name> in the given C<stash>
 which in the case of success contains an alias for the subroutine, and sets
 up caching info for this glob.
 
-The only significant values for C<flags> are GV_SUPER and SVf_UTF8.
+The only significant values for C<flags> are C<GV_SUPER> and C<SVf_UTF8>.
 
-GV_SUPER indicates that we want to look up the method in the superclasses
+C<GV_SUPER> indicates that we want to look up the method in the superclasses
 of the C<stash>.
 
 The
@@ -773,7 +770,7 @@ S_gv_fetchmeth_internal(pTHX_ HV* stash, SV* meth, const char* name, STRLEN len,
         }
        else if (stash == cachestash
              && len > 1 /* shortest is uc */ && HvNAMELEN_get(stash) == 4
-              && strnEQ(hvname, "CORE", 4)
+              && strEQs(hvname, "CORE")
               && S_maybe_add_coresub(aTHX_ NULL,topgv,name,len))
            goto have_gv;
     }
@@ -788,7 +785,7 @@ S_gv_fetchmeth_internal(pTHX_ HV* stash, SV* meth, const char* name, STRLEN len,
 
         if (!cstash) {
            Perl_ck_warner(aTHX_ packWARN(WARN_SYNTAX),
-                           "Can't locate package %"SVf" for @%"HEKf"::ISA",
+                           "Can't locate package %" SVf " for @%" HEKf "::ISA",
                           SVfARG(linear_sv),
                            HEKfARG(HvNAME_HEK(stash)));
             continue;
@@ -800,7 +797,7 @@ S_gv_fetchmeth_internal(pTHX_ HV* stash, SV* meth, const char* name, STRLEN len,
         if (!gvp) {
             if (len > 1 && HvNAMELEN_get(cstash) == 4) {
                 const char *hvname = HvNAME(cstash); assert(hvname);
-                if (strnEQ(hvname, "CORE", 4)
+                if (strEQs(hvname, "CORE")
                  && (candidate =
                       S_maybe_add_coresub(aTHX_ cstash,NULL,name,len)
                     ))
@@ -907,14 +904,14 @@ Perl_gv_fetchmeth_pv_autoload(pTHX_ HV *stash, const char *name, I32 level, U32
 /*
 =for apidoc gv_fetchmeth_pvn_autoload
 
-Same as gv_fetchmeth_pvn(), but looks for autoloaded subroutines too.
+Same as C<gv_fetchmeth_pvn()>, but looks for autoloaded subroutines too.
 Returns a glob for the subroutine.
 
 For an autoloaded subroutine without a GV, will create a GV even
-if C<level < 0>.  For an autoloaded subroutine without a stub, GvCV()
+if C<level < 0>.  For an autoloaded subroutine without a stub, C<GvCV()>
 of the result may be zero.
 
-Currently, the only significant value for C<flags> is SVf_UTF8.
+Currently, the only significant value for C<flags> is C<SVf_UTF8>.
 
 =cut
 */
@@ -956,7 +953,7 @@ Perl_gv_fetchmeth_pvn_autoload(pTHX_ HV *stash, const char *name, STRLEN len, I3
 
 Returns the glob which contains the subroutine to call to invoke the method
 on the C<stash>.  In fact in the presence of autoloading this may be the
-glob for "AUTOLOAD".  In this case the corresponding variable $AUTOLOAD is
+glob for "AUTOLOAD".  In this case the corresponding variable C<$AUTOLOAD> is
 already setup.
 
 The third parameter of C<gv_fetchmethod_autoload> determines whether
@@ -969,7 +966,7 @@ These functions grant C<"SUPER"> token
 as a prefix of the method name.  Note
 that if you want to keep the returned glob for a long time, you need to
 check for it being "AUTOLOAD", since at the later time the call may load a
-different subroutine due to $AUTOLOAD changing its value.  Use the glob
+different subroutine due to C<$AUTOLOAD> changing its value.  Use the glob
 created as a side effect to do this.
 
 These functions have the same side-effects as C<gv_fetchmeth> with
@@ -1006,16 +1003,14 @@ Perl_gv_fetchmethod_pv_flags(pTHX_ HV *stash, const char *name, U32 flags)
     return gv_fetchmethod_pvn_flags(stash, name, strlen(name), flags);
 }
 
-/* Don't merge this yet, as it's likely to get a len parameter, and possibly
-   even a U32 hash */
 GV *
 Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN len, U32 flags)
 {
-    const char *nend;
-    const char *nsplit = NULL;
+    const char * const origname = name;
+    const char * const name_end = name + len;
+    const char *last_separator = NULL;
     GV* gv;
     HV* ostash = stash;
-    const char * const origname = name;
     SV *const error_report = MUTABLE_SV(stash);
     const U32 autoload = flags & GV_AUTOLOAD;
     const U32 do_croak = flags & GV_CROAK;
@@ -1026,49 +1021,70 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
     if (SvTYPE(stash) < SVt_PVHV)
        stash = NULL;
     else {
-       /* The only way stash can become NULL later on is if nsplit is set,
+       /* The only way stash can become NULL later on is if last_separator is set,
           which in turn means that there is no need for a SVt_PVHV case
           the error reporting code.  */
     }
 
-    for (nend = name; *nend || nend != (origname + len); nend++) {
-       if (*nend == '\'') {
-           nsplit = nend;
-           name = nend + 1;
-       }
-       else if (*nend == ':' && *(nend + 1) == ':') {
-           nsplit = nend++;
-           name = nend + 1;
-       }
+    {
+        /* check if the method name is fully qualified or
+         * not, and separate the package name from the actual
+         * method name.
+         *
+         * leaves last_separator pointing to the beginning of the
+         * last package separator (either ' or ::) or 0
+         * if none was found.
+         *
+         * leaves name pointing at the beginning of the
+         * method name.
+         */
+        const char *name_cursor = name;
+        const char * const name_em1 = name_end - 1; /* name_end minus 1 */
+        for (name_cursor = name; name_cursor < name_end ; name_cursor++) {
+            if (*name_cursor == '\'') {
+                last_separator = name_cursor;
+                name = name_cursor + 1;
+            }
+            else if (name_cursor < name_em1 && *name_cursor == ':' && name_cursor[1] == ':') {
+                last_separator = name_cursor++;
+                name = name_cursor + 1;
+            }
+        }
     }
-    if (nsplit) {
-       if ((nsplit - origname) == 5 && memEQ(origname, "SUPER", 5)) {
+
+    /* did we find a separator? */
+    if (last_separator) {
+        STRLEN sep_len= last_separator - origname;
+        if ( memEQs(origname, sep_len, "SUPER")) {
            /* ->SUPER::method should really be looked up in original stash */
            stash = CopSTASH(PL_curcop);
            flags |= GV_SUPER;
            DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n",
                         origname, HvENAME_get(stash), name) );
        }
-       else if ((nsplit - origname) >= 7 &&
-                strnEQ(nsplit - 7, "::SUPER", 7)) {
+        else if ( sep_len >= 7 &&
+                strEQs(last_separator - 7, "::SUPER")) {
             /* don't autovifify if ->NoSuchStash::SUPER::method */
-           stash = gv_stashpvn(origname, nsplit - origname - 7, is_utf8);
+            stash = gv_stashpvn(origname, sep_len - 7, is_utf8);
            if (stash) flags |= GV_SUPER;
        }
        else {
             /* don't autovifify if ->NoSuchStash::method */
-            stash = gv_stashpvn(origname, nsplit - origname, is_utf8);
+            stash = gv_stashpvn(origname, sep_len, is_utf8);
        }
        ostash = stash;
     }
 
-    gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags);
+    gv = gv_fetchmeth_pvn(stash, name, name_end - name, 0, flags);
     if (!gv) {
+       /* This is the special case that exempts Foo->import and
+          Foo->unimport from being an error even if there's no
+         import/unimport subroutine */
        if (strEQ(name,"import") || strEQ(name,"unimport"))
            gv = MUTABLE_GV(&PL_sv_yes);
        else if (autoload)
            gv = gv_autoload_pvn(
-               ostash, name, nend - name, GV_AUTOLOAD_ISMETHOD|flags
+               ostash, name, name_end - name, GV_AUTOLOAD_ISMETHOD|flags
            );
        if (!gv && do_croak) {
            /* Right now this is exclusively for the benefit of S_method_common
@@ -1084,31 +1100,31 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
                                       HV_FETCH_ISEXISTS, NULL, 0)
                ) {
                    require_pv("IO/File.pm");
-                   gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags);
+                   gv = gv_fetchmeth_pvn(stash, name, name_end - name, 0, flags);
                    if (gv)
                        return gv;
                }
                Perl_croak(aTHX_
-                          "Can't locate object method \"%"UTF8f
-                          "\" via package \"%"HEKf"\"",
-                                   UTF8fARG(is_utf8, nend - name, name),
+                          "Can't locate object method \"%" UTF8f
+                          "\" via package \"%" HEKf "\"",
+                                   UTF8fARG(is_utf8, name_end - name, name),
                                     HEKfARG(HvNAME_HEK(stash)));
            }
            else {
                 SV* packnamesv;
 
-               if (nsplit) {
-                   packnamesv = newSVpvn_flags(origname, nsplit - origname,
+               if (last_separator) {
+                   packnamesv = newSVpvn_flags(origname, last_separator - origname,
                                                     SVs_TEMP | is_utf8);
                } else {
                    packnamesv = error_report;
                }
 
                Perl_croak(aTHX_
-                          "Can't locate object method \"%"UTF8f
-                          "\" via package \"%"SVf"\""
-                          " (perhaps you forgot to load \"%"SVf"\"?)",
-                          UTF8fARG(is_utf8, nend - name, name),
+                          "Can't locate object method \"%" UTF8f
+                          "\" via package \"%" SVf "\""
+                          " (perhaps you forgot to load \"%" SVf "\"?)",
+                          UTF8fARG(is_utf8, name_end - name, name),
                            SVfARG(packnamesv), SVfARG(packnamesv));
            }
        }
@@ -1200,8 +1216,9 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags)
      && (GvCVGEN(gv) || GvSTASH(gv) != stash)
     )
        Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
-                        "Use of inherited AUTOLOAD for non-method %"SVf
-                        "::%"UTF8f"() is deprecated",
+                        "Use of inherited AUTOLOAD for non-method %" SVf
+                        "::%" UTF8f "() is deprecated. This will be "
+                         "fatal in Perl 5.28",
                         SVfARG(packname),
                          UTF8fARG(is_utf8, len, name));
 
@@ -1294,51 +1311,72 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags)
 
 /* require_tie_mod() internal routine for requiring a module
  * that implements the logic of automatic ties like %! and %-
+ * It loads the module and then calls the _tie_it subroutine
+ * with the passed gv as an argument.
  *
  * The "gv" parameter should be the glob.
- * "varpv" holds the name of the var, used for error messages.
+ * "varname" holds the 1-char name of the var, used for error messages.
  * "namesv" holds the module name. Its refcount will be decremented.
- * "methpv" holds the method name to test for to check that things
- *   are working reasonably close to as expected.
  * "flags": if flag & 1 then save the scalar before loading.
  * For the protection of $! to work (it is set by this routine)
  * the sv slot must already be magicalized.
  */
-STATIC HV*
-S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methpv,const U32 flags)
+STATIC void
+S_require_tie_mod(pTHX_ GV *gv, const char varname, const char * name,
+                        STRLEN len, const U32 flags)
 {
-    HV* stash = gv_stashsv(namesv, 0);
+    const SV * const target = varname == '[' ? GvSV(gv) : (SV *)GvHV(gv);
 
     PERL_ARGS_ASSERT_REQUIRE_TIE_MOD;
 
-    if (!stash || !(gv_fetchmethod_autoload(stash, methpv, FALSE))) {
-       SV *module = newSVsv(namesv);
-       char varname = *varpv; /* varpv might be clobbered by load_module,
-                                 so save it. For the moment it's always
-                                 a single char. */
+    /* If it is not tied */
+    if (!target || !SvRMAGICAL(target)
+     || !mg_find(target,
+                 varname == '[' ? PERL_MAGIC_tiedscalar : PERL_MAGIC_tied))
+    {
+      HV *stash;
+      GV **gvp;
+      dSP;
+
+      ENTER;
+
+#define HV_FETCH_TIE_FUNC (GV **)hv_fetchs(stash, "_tie_it", 0)
+
+      /* Load the module if it is not loaded.  */
+      if (!(stash = gv_stashpvn(name, len, 0))
+       || !(gvp = HV_FETCH_TIE_FUNC) || !*gvp || !GvCV(*gvp))
+      {
+       SV * const module = newSVpvn(name, len);
        const char type = varname == '[' ? '$' : '%';
-#ifdef DEBUGGING
-       dSP;
-#endif
-       ENTER;
-       SAVEFREESV(namesv);
        if ( flags & 1 )
            save_scalar(gv);
        Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, module, NULL);
        assert(sp == PL_stack_sp);
-       stash = gv_stashsv(namesv, 0);
+       stash = gv_stashpvn(name, len, 0);
        if (!stash)
-           Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" is not available",
-                   type, varname, SVfARG(namesv));
-       else if (!gv_fetchmethod(stash, methpv))
-           Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" does not support method %s",
-                   type, varname, SVfARG(namesv), methpv);
-       LEAVE;
+           Perl_croak(aTHX_ "panic: Can't use %c%c because %s is not available",
+                   type, varname, name);
+       else if (!(gvp = HV_FETCH_TIE_FUNC) || !*gvp || !GvCV(*gvp))
+           Perl_croak(aTHX_ "panic: Can't use %c%c because %s does not define _tie_it",
+                   type, varname, name);
+      }
+      /* Now call the tie function.  It should be in *gvp.  */
+      assert(gvp); assert(*gvp); assert(GvCV(*gvp));
+      PUSHMARK(SP);
+      XPUSHs((SV *)gv);
+      PUTBACK;
+      call_sv((SV *)*gvp, G_VOID|G_DISCARD);
+      LEAVE;
     }
-    else SvREFCNT_dec_NN(namesv);
-    return stash;
 }
 
+/* add a require_tie_mod_s - the _s suffix is similar to pvs type suffixes,
+ * IOW it means we do STR_WITH_LEN() ourselves and the user should pass in
+ * a true string WITHOUT a len.
+ */
+#define require_tie_mod_s(gv, varname, name, flags) \
+    S_require_tie_mod(aTHX_ gv, varname, STR_WITH_LEN(name), flags)
+
 /*
 =for apidoc gv_stashpv
 
@@ -1362,7 +1400,7 @@ Returns a pointer to the stash for a specified package.  The C<namelen>
 parameter indicates the length of the C<name>, in bytes.  C<flags> is passed
 to C<gv_fetchpvn_flags()>, so if set to C<GV_ADD> then the package will be
 created if it does not already exist.  If the package does not exist and
-C<flags> is 0 (or any other setting that does not create packages) then NULL
+C<flags> is 0 (or any other setting that does not create packages) then C<NULL>
 is returned.
 
 Flags may be one of:
@@ -1374,7 +1412,7 @@ Flags may be one of:
     GV_NOEXPAND
     GV_ADDMG
 
-The most important of which are probably GV_ADD and SVf_UTF8.
+The most important of which are probably C<GV_ADD> and C<SVf_UTF8>.
 
 Note, use of C<gv_stashsv> instead of C<gv_stashpvn> where possible is strongly
 recommended for performance reasons.
@@ -1411,7 +1449,7 @@ S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags)
     tmpgv = gv_fetchpvn_flags(tmpbuf, tmplen, flags, SVt_PVHV);
     if (tmpbuf != smallbuf)
        Safefree(tmpbuf);
-    if (!tmpgv)
+    if (!tmpgv || !isGV_with_GP(tmpgv))
        return NULL;
     stash = GvHV(tmpgv);
     if (!(flags & ~GV_NOADD_MASK) && !stash) return NULL;
@@ -1432,11 +1470,11 @@ S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags)
 gv_stashsvpvn_cached
 
 Returns a pointer to the stash for a specified package, possibly
-cached.  Implements both C<gv_stashpvn> and C<gc_stashsv>.
+cached.  Implements both C<gv_stashpvn> and C<gv_stashsv>.
 
 Requires one of either namesv or namepv to be non-null.
 
-See C<gv_stashpvn> for details on "flags".
+See C<L</gv_stashpvn>> for details on "flags".
 
 Note the sv interface is strongly preferred for performance reasons.
 
@@ -1492,9 +1530,11 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
 /*
 =for apidoc gv_stashsv
 
-Returns a pointer to the stash for a specified package.  See C<gv_stashpvn>.
+Returns a pointer to the stash for a specified package.  See
+C<L</gv_stashpvn>>.
 
-Note this interface is strongly preferred over C<gv_stashpvn> for performance reasons.
+Note this interface is strongly preferred over C<gv_stashpvn> for performance
+reasons.
 
 =cut
 */
@@ -1552,7 +1592,10 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
 
     PERL_ARGS_ASSERT_PARSE_GV_STASH_NAME;
     
-    if (full_len > 2 && **name == '*' && isIDFIRST_lazy_if(*name + 1, is_utf8)) {
+    if (   full_len > 2
+        && **name == '*'
+        && isIDFIRST_lazy_if_safe(*name + 1, name_end, is_utf8))
+    {
         /* accidental stringify on a GV? */
         (*name)++;
     }
@@ -1600,8 +1643,8 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
                     *stash = GvHV(*gv) = newHV();
                     if (!HvNAME_get(*stash)) {
                         if (GvSTASH(*gv) == PL_defstash && *len == 6
-                            && strnEQ(*name, "CORE", 4))
-                            hv_name_set(*stash, "CORE", 4, 0);
+                            && strEQs(*name, "CORE"))
+                            hv_name_sets(*stash, "CORE", 0);
                         else
                             hv_name_set(
                                 *stash, nambeg, name_cursor-nambeg, is_utf8
@@ -1620,8 +1663,15 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
                 name_cursor++;
             *name = name_cursor+1;
             if (*name == name_end) {
-                if (!*gv)
-                    *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
+                if (!*gv) {
+                   *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
+                   if (SvTYPE(*gv) != SVt_PVGV) {
+                       gv_init_pvn(*gv, PL_defstash, "main::", 6,
+                                   GV_ADDMULTI);
+                       GvHV(*gv) =
+                           MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash));
+                   }
+               }
                 return TRUE;
             }
         }
@@ -1637,7 +1687,7 @@ S_gv_is_in_main(pTHX_ const char *name, STRLEN len, const U32 is_utf8)
     PERL_ARGS_ASSERT_GV_IS_IN_MAIN;
     
     /* If it's an alphanumeric variable */
-    if ( len && isIDFIRST_lazy_if(name, is_utf8) ) {
+    if ( len && isIDFIRST_lazy_if_safe(name, name + len, is_utf8) ) {
         /* Some "normal" variables are always in main::,
          * like INC or STDOUT.
          */
@@ -1727,14 +1777,14 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len,
                     /* diag_listed_as: Variable "%s" is not imported%s */
                     Perl_ck_warner_d(
                         aTHX_ packWARN(WARN_MISC),
-                        "Variable \"%c%"UTF8f"\" is not imported",
+                        "Variable \"%c%" UTF8f "\" is not imported",
                         sv_type == SVt_PVAV ? '@' :
                         sv_type == SVt_PVHV ? '%' : '$',
                         UTF8fARG(is_utf8, len, name));
                     if (GvCVu(*gvp))
                         Perl_ck_warner_d(
                             aTHX_ packWARN(WARN_MISC),
-                            "\t(Did you mean &%"UTF8f" instead?)\n",
+                            "\t(Did you mean &%" UTF8f " instead?)\n",
                             UTF8fARG(is_utf8, len, name)
                         );
                     *stash = NULL;
@@ -1751,9 +1801,9 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len,
         if (add && !PL_in_clean_all) {
             GV *gv;
             qerror(Perl_mess(aTHX_
-                 "Global symbol \"%s%"UTF8f
+                 "Global symbol \"%s%" UTF8f
                  "\" requires explicit package name (did you forget to "
-                 "declare \"my %s%"UTF8f"\"?)",
+                 "declare \"my %s%" UTF8f "\"?)",
                  (sv_type == SVt_PV ? "$"
                   : sv_type == SVt_PVAV ? "@"
                   : sv_type == SVt_PVHV ? "%"
@@ -1795,15 +1845,14 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len,
  * Note that it does not insert the GV into the stash prior to
  * magicalization, which some variables require need in order
  * to work (like $[, %+, %-, %!), so callers must take care of
- * that beforehand.
+ * that.
  * 
- * The return value has a specific meaning for gv_fetchpvn_flags:
- * If it returns true, and the gv is empty, it indicates that its
- * refcount should be decreased.
+ * It returns true if the gv did turn out to be magical one; i.e.,
+ * if gv_magicalize actually did something.
  */
 PERL_STATIC_INLINE bool
 S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
-               bool addmg, const svtype sv_type)
+                      const svtype sv_type)
 {
     SSize_t paren;
 
@@ -1814,21 +1863,31 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
           and VERSION. All the others apply only to the main stash or to
           CORE (which is checked right after this). */
        if (len) {
-           const char * const name2 = name + 1;
            switch (*name) {
            case 'E':
-               if (strnEQ(name2, "XPORT", 5))
+                if (
+                    len >= 6 && name[1] == 'X' &&
+                    (memEQs(name, len, "EXPORT")
+                    ||memEQs(name, len, "EXPORT_OK")
+                    ||memEQs(name, len, "EXPORT_FAIL")
+                    ||memEQs(name, len, "EXPORT_TAGS"))
+                )
                    GvMULTI_on(gv);
                break;
            case 'I':
-               if (strEQ(name2, "SA"))
+                if (memEQs(name, len, "ISA"))
                    gv_magicalize_isa(gv);
                break;
            case 'V':
-               if (strEQ(name2, "ERSION"))
+                if (memEQs(name, len, "VERSION"))
                    GvMULTI_on(gv);
                break;
            case 'a':
+                if (stash == PL_debstash && memEQs(name, len, "args")) {
+                   GvMULTI_on(gv_AVadd(gv));
+                   break;
+                }
+                /* FALLTHROUGH */
            case 'b':
                if (len == 1 && sv_type == SVt_PV)
                    GvMULTI_on(gv);
@@ -1836,13 +1895,13 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
            default:
                goto try_core;
            }
-           return addmg;
+           goto ret;
        }
       try_core:
        if (len > 1 /* shortest is uc */ && HvNAMELEN_get(stash) == 4) {
          /* Avoid null warning: */
          const char * const stashname = HvNAME(stash); assert(stashname);
-         if (strnEQ(stashname, "CORE", 4))
+         if (strEQs(stashname, "CORE"))
            S_maybe_add_coresub(aTHX_ 0, gv, name, len);
        }
     }
@@ -1863,27 +1922,32 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
        } else
 #endif
        {
-           const char * name2 = name + 1;
            switch (*name) {
            case 'A':
-               if (strEQ(name2, "RGV")) {
+                if (memEQs(name, len, "ARGV")) {
                    IoFLAGS(GvIOn(gv)) |= IOf_ARGV|IOf_START;
                }
-               else if (strEQ(name2, "RGVOUT")) {
+                else if (memEQs(name, len, "ARGVOUT")) {
                    GvMULTI_on(gv);
                }
                break;
            case 'E':
-               if (strnEQ(name2, "XPORT", 5))
+                if (
+                    len >= 6 && name[1] == 'X' &&
+                    (memEQs(name, len, "EXPORT")
+                    ||memEQs(name, len, "EXPORT_OK")
+                    ||memEQs(name, len, "EXPORT_FAIL")
+                    ||memEQs(name, len, "EXPORT_TAGS"))
+                )
                    GvMULTI_on(gv);
                break;
            case 'I':
-               if (strEQ(name2, "SA")) {
+                if (memEQs(name, len, "ISA")) {
                    gv_magicalize_isa(gv);
                }
                break;
            case 'S':
-               if (strEQ(name2, "IG")) {
+                if (memEQs(name, len, "SIG")) {
                    HV *hv;
                    I32 i;
                    if (!PL_psig_name) {
@@ -1914,63 +1978,80 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
                }
                break;
            case 'V':
-               if (strEQ(name2, "ERSION"))
+                if (memEQs(name, len, "VERSION"))
                    GvMULTI_on(gv);
                break;
             case '\003':        /* $^CHILD_ERROR_NATIVE */
-               if (strEQ(name2, "HILD_ERROR_NATIVE"))
+                if (memEQs(name, len, "\003HILD_ERROR_NATIVE"))
                    goto magicalize;
+                                /* @{^CAPTURE} %{^CAPTURE} */
+                if (memEQs(name, len, "\003APTURE")) {
+                    AV* const av = GvAVn(gv);
+                    UV uv= *name;
+
+                    sv_magic(MUTABLE_SV(av), (SV*)uv, PERL_MAGIC_regdata, NULL, 0);
+                    SvREADONLY_on(av);
+
+                    if (sv_type == SVt_PVHV || sv_type == SVt_PVGV)
+                        require_tie_mod_s(gv, '-', "Tie::Hash::NamedCapture",0);
+
+                } else          /* %{^CAPTURE_ALL} */
+                if (memEQs(name, len, "\003APTURE_ALL")) {
+                    if (sv_type == SVt_PVHV || sv_type == SVt_PVGV)
+                        require_tie_mod_s(gv, '+', "Tie::Hash::NamedCapture",0);
+                }
                break;
            case '\005':        /* $^ENCODING */
-                if (*name2 == '_') {
-                    name2++;
-                }
-               if (strEQ(name2, "NCODING"))
+                if (memEQs(name, len, "\005NCODING"))
                    goto magicalize;
                break;
            case '\007':        /* $^GLOBAL_PHASE */
-               if (strEQ(name2, "LOBAL_PHASE"))
+                if (memEQs(name, len, "\007LOBAL_PHASE"))
                    goto ro_magicalize;
                break;
            case '\014':        /* $^LAST_FH */
-               if (strEQ(name2, "AST_FH"))
+                if (memEQs(name, len, "\014AST_FH"))
                    goto ro_magicalize;
                break;
             case '\015':        /* $^MATCH */
-                if (strEQ(name2, "ATCH")) {
+                if (memEQs(name, len, "\015ATCH")) {
                     paren = RX_BUFF_IDX_CARET_FULLMATCH;
                     goto storeparen;
                 }
                 break;
            case '\017':        /* $^OPEN */
-               if (strEQ(name2, "PEN"))
+                if (memEQs(name, len, "\017PEN"))
                    goto magicalize;
                break;
            case '\020':        /* $^PREMATCH  $^POSTMATCH */
-                if (strEQ(name2, "REMATCH")) {
+                if (memEQs(name, len, "\020REMATCH")) {
                     paren = RX_BUFF_IDX_CARET_PREMATCH;
                     goto storeparen;
                 }
-               if (strEQ(name2, "OSTMATCH")) {
+                if (memEQs(name, len, "\020OSTMATCH")) {
                     paren = RX_BUFF_IDX_CARET_POSTMATCH;
                     goto storeparen;
                 }
                break;
            case '\024':        /* ${^TAINT} */
-               if (strEQ(name2, "AINT"))
+                if (memEQs(name, len, "\024AINT"))
                    goto ro_magicalize;
                break;
            case '\025':        /* ${^UNICODE}, ${^UTF8LOCALE} */
-               if (strEQ(name2, "NICODE"))
+                if (memEQs(name, len, "\025NICODE"))
                    goto ro_magicalize;
-               if (strEQ(name2, "TF8LOCALE"))
+                if (memEQs(name, len, "\025TF8LOCALE"))
                    goto ro_magicalize;
-               if (strEQ(name2, "TF8CACHE"))
+                if (memEQs(name, len, "\025TF8CACHE"))
                    goto magicalize;
                break;
            case '\027':        /* $^WARNING_BITS */
-               if (strEQ(name2, "ARNING_BITS"))
+                if (memEQs(name, len, "\027ARNING_BITS"))
+                   goto magicalize;
+#ifdef WIN32
+                else if (memEQs(name, len, "\027IN32_SLOPPY_STAT"))
                    goto magicalize;
+#endif
                break;
            case '1':
            case '2':
@@ -1986,7 +2067,7 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
                   this test  */
                 UV uv;
                 if (!grok_atoUV(name, &uv, NULL) || uv > I32_MAX)
-                    return addmg;
+                    goto ret;
                 /* XXX why are we using a SSize_t? */
                 paren = (SSize_t)(I32)uv;
                 goto storeparen;
@@ -2055,41 +2136,38 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
 
            sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len);
 
-            /* magicalization must be done before require_tie_mod is called */
+            /* magicalization must be done before require_tie_mod_s is called */
            if (sv_type == SVt_PVHV || sv_type == SVt_PVGV)
-           {
-               require_tie_mod(gv, "!", newSVpvs("Errno"), "TIEHASH", 1);
-                addmg = FALSE;
-           }
+                require_tie_mod_s(gv, '!', "Errno", 1);
 
            break;
-       case '-':               /* $- */
-       case '+':               /* $+ */
-       GvMULTI_on(gv); /* no used once warnings here */
-        {
-            AV* const av = GvAVn(gv);
-           SV* const avc = (*name == '+') ? MUTABLE_SV(av) : NULL;
-
-           sv_magic(MUTABLE_SV(av), avc, PERL_MAGIC_regdata, NULL, 0);
-            sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len);
-            if (avc)
-                SvREADONLY_on(GvSVn(gv));
-            SvREADONLY_on(av);
-
-            if (sv_type == SVt_PVHV || sv_type == SVt_PVGV)
-           {
-                require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0);
-                addmg = FALSE;
-           }
+       case '-':               /* $-, %-, @- */
+       case '+':               /* $+, %+, @+ */
+            GvMULTI_on(gv); /* no used once warnings here */
+            {   /* $- $+ */
+                sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len);
+                if (*name == '+')
+                    SvREADONLY_on(GvSVn(gv));
+            }
+            {   /* %- %+ */
+                if (sv_type == SVt_PVHV || sv_type == SVt_PVGV)
+                    require_tie_mod_s(gv, *name, "Tie::Hash::NamedCapture",0);
+            }
+            {   /* @- @+ */
+                AV* const av = GvAVn(gv);
+                const UV uv = (UV)*name;
 
+                sv_magic(MUTABLE_SV(av), (SV*)uv, PERL_MAGIC_regdata, NULL, 0);
+                SvREADONLY_on(av);
+            }
             break;
-       }
        case '*':               /* $* */
        case '#':               /* $# */
            if (sv_type == SVt_PV)
-               /* diag_listed_as: $* is no longer supported */
+               /* diag_listed_as: $* is no longer supported. Its use will be fatal in Perl 5.30 */
                Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
-                                "$%c is no longer supported", *name);
+                                "$%c is no longer supported. Its use "
+                                 "will be fatal in Perl 5.30", *name);
            break;
        case '\010':    /* $^H */
            {
@@ -2100,8 +2178,7 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
        case '[':               /* $[ */
            if ((sv_type == SVt_PV || sv_type == SVt_PVGV)
             && FEATURE_ARYBASE_IS_ENABLED) {
-               require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
-                addmg = FALSE;
+                require_tie_mod_s(gv,'[',"arybase",0);
            }
            else goto magicalize;
             break;
@@ -2169,7 +2246,13 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
        }
     }
 
-    return addmg;
+   ret:
+    /* Return true if we actually did something.  */
+    return GvAV(gv) || GvHV(gv) || GvIO(gv) || GvCV(gv)
+        || ( GvSV(gv) && (
+                           SvOK(GvSV(gv)) || SvMAGICAL(GvSV(gv))
+                         )
+           );
 }
 
 /* If we do ever start using this later on in the file, we need to make
@@ -2189,21 +2272,22 @@ S_maybe_multimagic_gv(pTHX_ GV *gv, const char *name, const svtype sv_type)
 
     if (sv_type == SVt_PVHV || sv_type == SVt_PVGV) {
         if (*name == '!')
-            require_tie_mod(gv, "!", newSVpvs("Errno"), "TIEHASH", 1);
+            require_tie_mod_s(gv, '!', "Errno", 1);
         else if (*name == '-' || *name == '+')
-            require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0);
+            require_tie_mod_s(gv, *name, "Tie::Hash::NamedCapture", 0);
     } else if (sv_type == SVt_PV) {
         if (*name == '*' || *name == '#') {
-            /* diag_listed_as: $* is no longer supported */
+            /* diag_listed_as: $# is no longer supported. Its use will be fatal in Perl 5.30 */
             Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED,
                                              WARN_SYNTAX),
-                             "$%c is no longer supported", *name);
+                             "$%c is no longer supported. Its use "
+                             "will be fatal in Perl 5.30", *name);
         }
     }
     if (sv_type==SVt_PV || sv_type==SVt_PVGV) {
       switch (*name) {
       case '[':
-          require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
+          require_tie_mod_s(gv,'[',"arybase",0);
           break;
 #ifdef PERL_SAWAMPERSAND
       case '`':
@@ -2294,7 +2378,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                 maybe_multimagic_gv(gv, name, sv_type);
            }
            else if (len == 3 && sv_type == SVt_PVAV
-                 && strnEQ(name, "ISA", 3)
+                 && strEQs(name, "ISA")
                  && (!GvAV(gv) || !SvSMAGICAL(GvAV(gv))))
                gv_magicalize_isa(gv);
        }
@@ -2325,40 +2409,33 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
 
     if (add & GV_ADDWARN)
        Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL),
-               "Had to create %"UTF8f" unexpectedly",
+               "Had to create %" UTF8f " unexpectedly",
                 UTF8fARG(is_utf8, name_end-nambeg, nambeg));
     gv_init_pvn(gv, stash, name, len, (add & GV_ADDMULTI)|is_utf8);
 
-    if ( isIDFIRST_lazy_if(name, is_utf8) && !ckWARN(WARN_ONCE) )
+    if (   full_len != 0
+        && isIDFIRST_lazy_if_safe(name, name + full_len, is_utf8)
+        && !ckWARN(WARN_ONCE) )
+    {
         GvMULTI_on(gv) ;
-
-    /* First, store the gv in the symtab if we're adding magic,
-     * but only for non-empty GVs
-     */
-#define GvEMPTY(gv)      !(GvAV(gv) || GvHV(gv) || GvIO(gv) \
-                        || GvCV(gv) || (GvSV(gv) && SvOK(GvSV(gv))))
-    
-    if ( addmg && !GvEMPTY(gv) ) {
-        (void)hv_store(stash,name,len,(SV *)gv,0);
     }
 
     /* set up magic where warranted */
-    if ( gv_magicalize(gv, stash, name, len, addmg, sv_type) ) {
+    if ( gv_magicalize(gv, stash, name, len, sv_type) ) {
         /* See 23496c6 */
-        if (GvEMPTY(gv)) {
-            if ( GvSV(gv) && SvMAGICAL(GvSV(gv)) ) {
-                /* The GV was and still is "empty", except that now
-                 * it has the magic flags turned on, so we want it
+        if (addmg) {
+                /* gv_magicalize magicalised this gv, so we want it
                  * stored in the symtab.
+                 * Effectively the caller is asking, ‘Does this gv exist?’ 
+                 * And we respond, ‘Er, *now* it does!’
                  */
                 (void)hv_store(stash,name,len,(SV *)gv,0);
-            }
-            else {
-                /* Most likely the temporary GV created above */
+        }
+    }
+    else if (addmg) {
+                /* The temporary GV created above */
                 SvREFCNT_dec_NN(gv);
                 gv = NULL;
-            }
-        }
     }
     
     if (gv) gv_init_svtype(gv, faking_it ? SVt_PVCV : sv_type);
@@ -2408,10 +2485,10 @@ Perl_gv_check(pTHX_ HV *stash)
 
     PERL_ARGS_ASSERT_GV_CHECK;
 
-    if (!HvARRAY(stash))
+    if (!SvOOK(stash))
        return;
 
-    assert(SvOOK(stash));
+    assert(HvARRAY(stash));
 
     for (i = 0; i <= (I32) HvMAX(stash); i++) {
         const HE *entry;
@@ -2420,7 +2497,10 @@ Perl_gv_check(pTHX_ HV *stash)
        for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
             GV *gv;
             HV *hv;
-           if (HeKEY(entry)[HeKLEN(entry)-1] == ':' &&
+           STRLEN keylen = HeKLEN(entry);
+            const char * const key = HeKEY(entry);
+
+           if (keylen >= 2 && key[keylen-2] == ':'  && key[keylen-1] == ':' &&
                (gv = MUTABLE_GV(HeVAL(entry))) && isGV(gv) && (hv = GvHV(gv)))
            {
                if (hv != PL_defstash && hv != stash
@@ -2429,8 +2509,12 @@ Perl_gv_check(pTHX_ HV *stash)
                 )
                     gv_check(hv);              /* nested package */
            }
-            else if ( *HeKEY(entry) != '_'
-                        && isIDFIRST_lazy_if(HeKEY(entry), HeUTF8(entry)) ) {
+            else if (   HeKLEN(entry) != 0
+                     && *HeKEY(entry) != '_'
+                     && isIDFIRST_lazy_if_safe(HeKEY(entry),
+                                               HeKEY(entry) + HeKLEN(entry),
+                                               HeUTF8(entry)) )
+            {
                 const char *file;
                gv = MUTABLE_GV(HeVAL(entry));
                if (SvTYPE(gv) != SVt_PVGV || GvMULTI(gv))
@@ -2444,7 +2528,7 @@ Perl_gv_check(pTHX_ HV *stash)
                    = gv_fetchfile_flags(file, HEK_LEN(GvFILE_HEK(gv)), 0);
 #endif
                Perl_warner(aTHX_ packWARN(WARN_ONCE),
-                       "Name \"%"HEKf"::%"HEKf
+                       "Name \"%" HEKf "::%" HEKf
                        "\" used only once: possible typo",
                             HEKfARG(HvNAME_HEK(stash)),
                             HEKfARG(GvNAME_HEK(gv)));
@@ -2460,7 +2544,7 @@ Perl_newGVgen_flags(pTHX_ const char *pack, U32 flags)
     PERL_ARGS_ASSERT_NEWGVGEN_FLAGS;
     assert(!(flags & ~SVf_UTF8));
 
-    return gv_fetchpv(Perl_form(aTHX_ "%"UTF8f"::_GEN_%ld",
+    return gv_fetchpv(Perl_form(aTHX_ "%" UTF8f "::_GEN_%ld",
                                 UTF8fARG(flags, strlen(pack), pack),
                                 (long)PL_gensym++),
                       GV_ADD, SVt_PVGV);
@@ -2540,7 +2624,7 @@ Perl_gp_free(pTHX_ GV *gv)
         const HEK *hvname_hek = HvNAME_HEK(hv);
         if (PL_stashcache && hvname_hek) {
            DEBUG_o(Perl_deb(aTHX_
-                          "gp_free clearing PL_stashcache for '%"HEKf"'\n",
+                          "gp_free clearing PL_stashcache for '%" HEKf "'\n",
                            HEKfARG(hvname_hek)));
            (void)hv_deletehek(PL_stashcache, hvname_hek, G_DISCARD);
         }
@@ -2709,7 +2793,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
                GV *ngv = NULL;
                SV *gvsv = GvSV(gv);
 
-               DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%"SVf256\
+               DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%" SVf256\
                        "\" for overloaded \"%s\" in package \"%.256s\"\n",
                             (void*)GvSV(gv), cp, HvNAME(stash)) );
                if (!gvsv || !SvPOK(gvsv)
@@ -2724,9 +2808,9 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
                                                     ? gvsv
                                                     : newSVpvs_flags("???", SVs_TEMP);
                        /* diag_listed_as: Can't resolve method "%s" overloading "%s" in package "%s" */
-                       Perl_croak(aTHX_ "%s method \"%"SVf256
+                       Perl_croak(aTHX_ "%s method \"%" SVf256
                                    "\" overloading \"%s\" "\
-                                   "in package \"%"HEKf256"\"",
+                                   "in package \"%" HEKf256 "\"",
                                   (GvCVGEN(gv) ? "Stub found while resolving"
                                    : "Can't resolve"),
                                   SVfARG(name), cp,
@@ -3212,7 +3296,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
        SV *msg;
        if (off==-1) off=method;
        msg = sv_2mortal(Perl_newSVpvf(aTHX_
-                     "Operation \"%s\": no method found,%sargument %s%"SVf"%s%"SVf,
+                     "Operation \"%s\": no method found,%sargument %s%" SVf "%s%" SVf,
                      AMG_id2name(method + assignshift),
                      (flags & AMGf_unary ? " " : "\n\tleft "),
                      SvAMAGIC(left)?
@@ -3230,9 +3314,9 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
                        SVfARG(sv_2mortal(newSVhek(HvNAME_HEK(SvSTASH(SvRV(right)))))):
                        SVfARG(&PL_sv_no)));
         if (use_default_op) {
-         DEBUG_o( Perl_deb(aTHX_ "%"SVf, SVfARG(msg)) );
+         DEBUG_o( Perl_deb(aTHX_ "%" SVf, SVfARG(msg)) );
        } else {
-         Perl_croak(aTHX_ "%"SVf, SVfARG(msg));
+         Perl_croak(aTHX_ "%" SVf, SVfARG(msg));
        }
        return NULL;
       }
@@ -3303,7 +3387,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
 #ifdef DEBUGGING
   if (!notfound) {
     DEBUG_o(Perl_deb(aTHX_
-                    "Overloaded operator \"%s\"%s%s%s:\n\tmethod%s found%s in package %"SVf"%s\n",
+                    "Overloaded operator \"%s\"%s%s%s:\n\tmethod%s found%s in package %" SVf "%s\n",
                     AMG_id2name(off),
                     method+assignshift==off? "" :
                     " (initially \"",
@@ -3360,7 +3444,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     SV* res;
     const bool oldcatch = CATCH_GET;
     I32 oldmark, nret;
-    int gimme = force_scalar ? G_SCALAR : GIMME_V;
+    U8 gimme = force_scalar ? G_SCALAR : GIMME_V;
 
     CATCH_SET(TRUE);
     Zero(&myop, 1, BINOP);
@@ -3490,7 +3574,7 @@ Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags)
     PERL_ARGS_ASSERT_GV_NAME_SET;
 
     if (len > I32_MAX)
-       Perl_croak(aTHX_ "panic: gv name too long (%"UVuf")", (UV) len);
+       Perl_croak(aTHX_ "panic: gv name too long (%" UVuf ")", (UV) len);
 
     if (!(flags & GV_ADD) && GvNAME_HEK(gv)) {
        unshare_hek(GvNAME_HEK(gv));