warn on C<my($foo,$foo)>
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 69c6b45..9b2284d 100644 (file)
--- a/op.c
+++ b/op.c
@@ -131,12 +131,11 @@ pad_allocmy(char *name)
        for (off = AvFILLp(PL_comppad_name); off > PL_comppad_name_floor; off--) {
            if ((sv = svp[off])
                && sv != &PL_sv_undef
-               && SvIVX(sv) == 999999999       /* var is in open scope */
                && strEQ(name, SvPVX(sv)))
            {
                warner(WARN_UNSAFE,
-                       "\"my\" variable %s masks earlier declaration in same scope", 
-                       name);
+                       "\"my\" variable %s masks earlier declaration in same %s", 
+                       name, (SvIVX(sv) == 999999999 ? "scope" : "statement"));
                break;
            }
        }
@@ -1135,7 +1134,8 @@ mod(OP *o, I32 type)
        if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN)
            break;
        yyerror(form("Can't modify %s in %s",
-                    op_desc[o->op_type],
+                    (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL)
+                     ? "do block" : op_desc[o->op_type]),
                     type ? op_desc[type] : "local"));
        return o;
 
@@ -1264,7 +1264,9 @@ mod(OP *o, I32 type)
        break;
 
     case OP_NULL:
-       if (!(o->op_flags & OPf_KIDS))
+       if (o->op_flags & OPf_SPECIAL)          /* do BLOCK */
+           goto nomod;
+       else if (!(o->op_flags & OPf_KIDS))
            break;
        if (o->op_targ != OP_LIST) {
            mod(cBINOPo->op_first, type);
@@ -2133,11 +2135,11 @@ pmtrans(OP *o, OP *expr, OP *repl)
                diff = val - nextmin;
                if (diff > 0) {
                    t = uv_to_utf8(tmpbuf,nextmin);
-                   sv_catpvn(transv, tmpbuf, t - tmpbuf);
+                   sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
                    if (diff > 1) {
                        t = uv_to_utf8(tmpbuf, val - 1);
                        sv_catpvn(transv, "\377", 1);
-                       sv_catpvn(transv, tmpbuf, t - tmpbuf);
+                       sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
                    }
                }
                if (*s == 0xff)
@@ -2146,18 +2148,27 @@ pmtrans(OP *o, OP *expr, OP *repl)
                    nextmin = val + 1;
            }
            t = uv_to_utf8(tmpbuf,nextmin);
-           sv_catpvn(transv, tmpbuf, t - tmpbuf);
+           sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
            t = uv_to_utf8(tmpbuf, 0x7fffffff);
            sv_catpvn(transv, "\377", 1);
-           sv_catpvn(transv, tmpbuf, t - tmpbuf);
-           t = SvPVX(transv);
+           sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
+           t = (U8*)SvPVX(transv);
            tlen = SvCUR(transv);
            tend = t + tlen;
        }
        else if (!rlen && !del) {
            r = t; rlen = tlen; rend = tend;
-           if (!squash && to_utf && from_utf)
-               o->op_private |= OPpTRANS_COUNTONLY;
+       }
+       if (!squash) {
+           if (to_utf && from_utf) {   /* only counting characters */
+               if (t == r || (tlen == rlen && memEQ(t, r, tlen)))
+                   o->op_private |= OPpTRANS_IDENTICAL;
+           }
+           else {      /* straight latin-1 translation */
+               if (tlen == 4 && memEQ(t, "\0\377\303\277", 4) &&
+                   rlen == 4 && memEQ(r, "\0\377\303\277", 4))
+                   o->op_private |= OPpTRANS_IDENTICAL;
+           }
        }
 
        while (t < tend || tfirst <= tlast) {
@@ -2286,7 +2297,7 @@ pmtrans(OP *o, OP *expr, OP *repl)
        if (!rlen && !del) {
            r = t; rlen = tlen;
            if (!squash)
-               o->op_private |= OPpTRANS_COUNTONLY;
+               o->op_private |= OPpTRANS_IDENTICAL;
        }
        for (i = 0; i < 256; i++)
            tbl[i] = -1;
@@ -4010,6 +4021,7 @@ newXS(char *name, void (*subaddr) (CV * _CPERLproto), char *filename)
            if (!PL_initav)
                PL_initav = newAV();
            av_push(PL_initav, (SV *)cv);
+           GvCV(gv) = 0;
        }
     }
     else
@@ -4686,6 +4698,8 @@ ck_index(OP *o)
 {
     if (o->op_flags & OPf_KIDS) {
        OP *kid = cLISTOPo->op_first->op_sibling;       /* get past pushmark */
+       if (kid)
+           kid = kid->op_sibling;                      /* get past "big" */
        if (kid && kid->op_type == OP_CONST)
            fbm_compile(((SVOP*)kid)->op_sv, 0);
     }