Make the "uninit variable" warning to say "concat or string"
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index 5db5eab..66d22bc 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -146,22 +146,36 @@ PP(pp_concat)
     dPOPTOPssrl;
     STRLEN len;
     char *s;
+    bool left_utf = DO_UTF8(left);
+    bool right_utf = DO_UTF8(right);
 
     if (TARG != left) {
+       if (right_utf && !left_utf)
+           sv_utf8_upgrade(left);
        s = SvPV(left,len);
+       SvUTF8_off(TARG);
        if (TARG == right) {
+           if (left_utf && !right_utf)
+               sv_utf8_upgrade(right);
            sv_insert(TARG, 0, 0, s, len);
+           if (left_utf || right_utf)
+               SvUTF8_on(TARG);
            SETs(TARG);
            RETURN;
        }
        sv_setpvn(TARG,s,len);
     }
-    else if (SvGMAGICAL(TARG))
+    else if (SvGMAGICAL(TARG)) {
        mg_get(TARG);
+       if (right_utf && !left_utf)
+           sv_utf8_upgrade(left);
+    }
     else if (!SvOK(TARG) && SvTYPE(TARG) <= SVt_PVMG) {
        sv_setpv(TARG, "");     /* Suppress warning. */
        s = SvPV_force(TARG, len);
     }
+    if (left_utf && !right_utf)
+       sv_utf8_upgrade(right);
     s = SvPV(right,len);
     if (SvOK(TARG)) {
 #if defined(PERL_Y2KWARN)
@@ -176,19 +190,12 @@ PP(pp_concat)
            }
        }
 #endif
-       if (DO_UTF8(right))
-           sv_utf8_upgrade(TARG);
        sv_catpvn(TARG,s,len);
-       if (!IN_BYTE) {
-           if (SvUTF8(right))
-               SvUTF8_on(TARG);
-       }
-       else if (!SvUTF8(right)) {
-           SvUTF8_off(TARG);
-       }
     }
     else
        sv_setpvn(TARG,s,len);  /* suppress warning */
+    if (left_utf || right_utf)
+       SvUTF8_on(TARG);
     SETTARG;
     RETURN;
   }
@@ -455,7 +462,7 @@ PP(pp_rv2av)
            
            if (SvTYPE(sv) != SVt_PVGV) {
                char *sym;
-               STRLEN n_a;
+               STRLEN len;
 
                if (SvGMAGICAL(sv)) {
                    mg_get(sv);
@@ -474,13 +481,17 @@ PP(pp_rv2av)
                    }
                    RETSETUNDEF;
                }
-               sym = SvPV(sv,n_a);
+               sym = SvPV(sv,len);
                if ((PL_op->op_flags & OPf_SPECIAL) &&
                    !(PL_op->op_flags & OPf_MOD))
                {
                    gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVAV);
-                   if (!gv)
+                   if (!gv
+                       && (!is_gv_magical(sym,len,0)
+                           || !(gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV))))
+                   {
                        RETSETUNDEF;
+                   }
                }
                else {
                    if (PL_op->op_private & HINT_STRICT_REFS)
@@ -555,7 +566,7 @@ PP(pp_rv2hv)
            
            if (SvTYPE(sv) != SVt_PVGV) {
                char *sym;
-               STRLEN n_a;
+               STRLEN len;
 
                if (SvGMAGICAL(sv)) {
                    mg_get(sv);
@@ -574,13 +585,17 @@ PP(pp_rv2hv)
                    }
                    RETSETUNDEF;
                }
-               sym = SvPV(sv,n_a);
+               sym = SvPV(sv,len);
                if ((PL_op->op_flags & OPf_SPECIAL) &&
                    !(PL_op->op_flags & OPf_MOD))
                {
                    gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVHV);
-                   if (!gv)
+                   if (!gv
+                       && (!is_gv_magical(sym,len,0)
+                           || !(gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV))))
+                   {
                        RETSETUNDEF;
+                   }
                }
                else {
                    if (PL_op->op_private & HINT_STRICT_REFS)
@@ -1375,8 +1390,7 @@ Perl_do_readline(pTHX)
 /* delay EOF state for a snarfed empty file */
 #define SNARF_EOF(gimme,rs,io,sv) \
     (gimme != G_SCALAR || SvCUR(sv)                                    \
-     || !RsSNARF(rs) || (IoFLAGS(io) & IOf_NOLINE)                     \
-     || ((IoFLAGS(io) |= IOf_NOLINE), FALSE))
+     || (IoFLAGS(io) & IOf_NOLINE) || !RsSNARF(rs))
 
     for (;;) {
        if (!sv_gets(sv, fp, offset)
@@ -1409,6 +1423,7 @@ Perl_do_readline(pTHX)
            SvTAINTED_on(sv);
        }
        IoLINES(io)++;
+       IoFLAGS(io) |= IOf_NOLINE;
        SvSETMAGIC(sv);
        XPUSHs(sv);
        if (type == OP_GLOB) {
@@ -1872,7 +1887,7 @@ PP(pp_subst)
            SPAGAIN;
            PUSHs(sv_2mortal(newSViv((I32)iters)));
        }
-       (void)SvPOK_only(TARG);
+       (void)SvPOK_only_UTF8(TARG);
        TAINT_IF(rxtainted);
        if (SvSMAGICAL(TARG)) {
            PUTBACK;
@@ -2221,7 +2236,9 @@ S_get_db_sub(pTHX_ SV **svp, CV *cv)
                    && (gv = (GV*)*svp) ))) {
            /* Use GV from the stack as a fallback. */
            /* GV is potentially non-unique, or contain different CV. */
-           sv_setsv(dbsv, newRV((SV*)cv));
+           SV *tmp = newRV((SV*)cv);
+           sv_setsv(dbsv, tmp);
+           SvREFCNT_dec(tmp);
        }
        else {
            gv_efullname3(dbsv, gv, Nullch);
@@ -2644,6 +2661,7 @@ try_autoload:
            cx->blk_sub.savearray = GvAV(PL_defgv);
            GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
 #endif /* USE_THREADS */
+           cx->blk_sub.oldcurpad = PL_curpad;
            cx->blk_sub.argarray = av;
            ++MARK;
 
@@ -2868,6 +2886,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
        char* leaf = name;
        char* sep = Nullch;
        char* p;
+       GV* gv;
 
        for (p = name; *p; p++) {
            if (*p == '\'')
@@ -2883,9 +2902,18 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
            packname = name;
            packlen = sep - name;
        }
-       Perl_croak(aTHX_
-                  "Can't locate object method \"%s\" via package \"%s\"",
-                  leaf, packname);
+       gv = gv_fetchpv(packname, 0, SVt_PVHV);
+       if (gv && isGV(gv)) {
+           Perl_croak(aTHX_
+                      "Can't locate object method \"%s\" via package \"%s\"",
+                      leaf, packname);
+       }
+       else {
+           Perl_croak(aTHX_
+                      "Can't locate object method \"%s\" via package \"%s\""
+                      " (perhaps you forgot to load \"%s\"?)",
+                      leaf, packname, packname);
+       }
     }
     return isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv;
 }